Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add debug lib #327

Merged
merged 3 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions frontend/player/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,7 @@ function* computeInstants(replayApi: ReplayApi, replayContext: ReplayContext) {

// Get Redux state and context state and store them
const instantState = createDraft(replayStore.getState());
const context = quickAlgoLibraries.getContext(null, 'replay');
instantState.task.state = getCurrentImmerState(context.getInnerState());
instantState.task.state = quickAlgoLibraries.getLibrariesInnerState('replay');
instant.state = finishDraft(instantState);

Object.freeze(instant);
Expand Down
7 changes: 5 additions & 2 deletions frontend/stepper/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {QuickAlgoLibrary} from '../task/libs/quickalgo_library';
import {CodecastPlatform} from './platforms';
import {LibraryTestResult} from '../task/libs/library_test_result';
import {createQuickAlgoLibraryExecutor} from './quickalgo_executor';
import {appSelect} from '../hooks';

export interface QuickalgoLibraryCall {
module: string,
Expand Down Expand Up @@ -85,7 +86,7 @@ export interface StepperApi {
addSaga?: Function,
onEffect?: Function,
addBuiltin?: Function,
buildState?: (state: AppStoreReplay, environment: string) => Generator<any, StepperState>,
buildState?: () => Generator<any, StepperState>,
rootStepperSaga?: any,
executeEffects?: Function,
}
Expand Down Expand Up @@ -136,7 +137,9 @@ export default function(bundle: Bundle) {


/* Build a stepper state from the given init data. */
function* buildState(state: AppStoreReplay, environment: string): Generator<any, StepperState> {
function* buildState(): Generator<any, StepperState> {
const state = yield* appSelect();
const environment = state.environment;
const {platform} = state.options;

log.getLogger('stepper').debug('do build state', state, environment);
Expand Down
37 changes: 12 additions & 25 deletions frontend/stepper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@ import {TermBuffer} from "./io/terminal";
import {delay} from "../player/sagas";
import {Bundle} from "../linker";
import {App, Codecast} from "../index";
import {mainQuickAlgoLogger, quickAlgoLibraries, QuickAlgoLibrariesActionType} from "../task/libs/quickalgo_libraries";
import {
mainQuickAlgoLogger,
quickAlgoLibraries,
QuickAlgoLibrariesActionType,
quickAlgoLibraryResetAndReloadStateSaga
} from "../task/libs/quickalgo_libraries";
import {selectCurrentTestData, taskResetDone, updateCurrentTestId} from "../task/task_slice";
import {getCurrentImmerState} from "../task/utils";
import PythonRunner from "./python/python_runner";
Expand Down Expand Up @@ -161,7 +166,6 @@ const initialStateStepperState = {
stackSize: 4096
},
isFinished: false, // Only used for python
contextState: {} as any,
currentBlockId: null, // Only used for Blockly
};

Expand Down Expand Up @@ -574,7 +578,6 @@ function stepperProgressReducer(state: AppStoreReplay, {payload: {stepperContext
/**
* TODO: stepperState comes from an action so it's not an immer draft.
*/
// log.getLogger('stepper').debug('previous state', stepperContext.state.contextState, 'and progress', progress);
stepperContext.state = {...stepperContext.state};

if (false !== progress) {
Expand All @@ -588,11 +591,7 @@ function stepperProgressReducer(state: AppStoreReplay, {payload: {stepperContext
enrichStepperState(stepperContext.state, 'Stepper.Progress', stepperContext);
}

const context = quickAlgoLibraries.getContext(null, state.environment);
if (context) {
state.task.state = getCurrentImmerState(context.getInnerState());
}

state.task.state = quickAlgoLibraries.getLibrariesInnerState(state.environment);
state.stepper.currentStepperState = stepperContext.state;
if (state.compile.status === CompileStatus.Error) {
state.stepper.currentStepperState.isFinished = false;
Expand Down Expand Up @@ -740,15 +739,10 @@ function* compileSucceededSaga(app: App) {
Codecast.runner = yield* call(createRunnerSaga);

/* Build the stepper state. This automatically runs into user source code. */
let state = yield* appSelect();

let stepperState = yield* call(app.stepperApi.buildState, state, state.environment);
log.getLogger('stepper').debug('[stepper init] current state', state.task.state, 'context state', stepperState.contextState);
const newState = yield* appSelect();
log.getLogger('stepper').debug('[stepper init] new state', newState.task.state);

let stepperState = yield* call(app.stepperApi.buildState);
const state = yield* appSelect();
log.getLogger('stepper').debug('[stepper init] new state', state.task.state);
// buildState may have triggered an error.
state = yield* appSelect();
if (state.compile.status !== 'error') {
/* Enable the stepper */
yield* put({type: ActionTypes.StepperEnabled});
Expand Down Expand Up @@ -856,8 +850,6 @@ function* stepperInteractSaga(app: App, {payload: {stepperContext, arg}, meta: {
let state = yield* appSelect();

if (!state.stepper.synchronizingAnalysis) {
// log.getLogger('stepper').debug('current stepper state', stepperContext.state.contextState);

/* Emit a progress action so that an up-to-date state gets displayed. */

yield* put({type: ActionTypes.StepperProgress, payload: {stepperContext, progress: arg.progress}});
Expand All @@ -871,8 +863,6 @@ function* stepperInteractSaga(app: App, {payload: {stepperContext, arg}, meta: {
completed = yield* call(saga, stepperContext);
}

// log.getLogger('stepper').debug('current stepper state2', stepperContext.state.contextState);

if (state.stepper.synchronizingAnalysis) {
yield* call(resolve, completed);
return;
Expand All @@ -883,8 +873,6 @@ function* stepperInteractSaga(app: App, {payload: {stepperContext, arg}, meta: {
state = yield* appSelect();
stepperContext.state = {...getCurrentStepperState(state)};

// log.getLogger('stepper').debug('current stepper state3', stepperContext.state.contextState);

/* Continue stepper execution, passing the saga's return value as the
result of yielding the interact effect. */
yield* call(resolve, completed);
Expand Down Expand Up @@ -1071,9 +1059,8 @@ function* stepperRunFromBeginningIfNecessary(stepperContext: StepperContext) {
taskContext.display = false;
}
stepperContext.taskDisplayNoneStatus = 'running';
taskContext.resetAndReloadState(selectCurrentTestData(state), state);
stepperContext.state.contextState = getCurrentImmerState(taskContext.getInnerState());
log.getLogger('stepper').debug('current task state', taskContext.getInnerState());

yield* call(quickAlgoLibraryResetAndReloadStateSaga);

if (!Codecast.runner) {
Codecast.runner = yield* call(createRunnerSaga);
Expand Down
12 changes: 0 additions & 12 deletions frontend/stepper/quickalgo_executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ class QuickalgoExecutor {
context.infos.actionDelay = context.plannedNewDelay;
}

if (this.stepperContext.state) {
log.getLogger('quickalgo_executor').debug('[quickalgo_executor] stepper context before', this.stepperContext.state.contextState);
}

if (this.stepperContext.quickAlgoCallsLogger) {
const quickAlgoLibraryCall: QuickalgoLibraryCall = {module, action, args};
this.stepperContext.quickAlgoCallsLogger(quickAlgoLibraryCall);
Expand Down Expand Up @@ -119,14 +115,6 @@ class QuickalgoExecutor {
const newState = getCurrentImmerState(context.getInnerState());
log.getLogger('quickalgo_executor').debug('[quickalgo_executor] NEW LIBRARY STATE', newState);

if (this.stepperContext.state) {
this.stepperContext.state = {
...this.stepperContext.state,
contextState: newState,
};
log.getLogger('quickalgo_executor').debug('[quickalgo_executor] stepper context after', this.stepperContext.state.contextState);
}

if (context.callsToExecute.length) {
const newCall = context.callsToExecute.pop();
libraryCallResult = await this.execute(module, newCall.action, newCall.args, newCall.callback);
Expand Down
15 changes: 7 additions & 8 deletions frontend/stepper/replay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import {ActionTypes as PlayerActionTypes} from '../player/actionTypes';
import {ActionTypes, stepperRunBackgroundFinished} from './actionTypes';
import {PlayerInstant} from '../player';
import log from 'loglevel';
import {mainQuickAlgoLogger, quickAlgoLibraries} from '../task/libs/quickalgo_libraries';
import {
mainQuickAlgoLogger,
quickAlgoLibraries,
quickAlgoLibraryResetAndReloadStateSaga
} from '../task/libs/quickalgo_libraries';
import {selectCurrentTestData} from '../task/task_slice';
import {getCurrentStepperState, isStepperInterrupting} from './selectors';
import {App, Codecast} from '../index';
Expand Down Expand Up @@ -43,11 +47,7 @@ export function addStepperRecordAndReplayHooks(app: App) {
yield* put({type: ActionTypes.StepperExit});
replayContext.addSaga(function* () {
log.getLogger('stepper').debug('make reset saga');
const context = quickAlgoLibraries.getContext(null, 'main');
if (context) {
const state = yield* appSelect();
context.resetAndReloadState(selectCurrentTestData(state), state);
}
yield* call(quickAlgoLibraryResetAndReloadStateSaga);
})
});

Expand Down Expand Up @@ -188,8 +188,7 @@ export function addStepperRecordAndReplayHooks(app: App) {
});

replayApi.on('stepper.restart', function* () {
const state = yield* appSelect();
const stepperState = yield* call(app.stepperApi.buildState, state, state.environment);
const stepperState = yield* call(app.stepperApi.buildState);

yield* put({type: ActionTypes.StepperEnabled});
yield* put({type: ActionTypes.StepperRestart, payload: {stepperState}});
Expand Down
3 changes: 1 addition & 2 deletions frontend/submission/submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {updateCurrentTestId} from '../task/task_slice';
import {stepperClearError, stepperDisplayError} from '../stepper/actionTypes';
import {
quickAlgoLibraries,
QuickAlgoLibrariesActionType,
quickAlgoLibraryResetAndReloadStateSaga
} from '../task/libs/quickalgo_libraries';
import {CodecastPlatform} from '../stepper/platforms';
Expand Down Expand Up @@ -172,7 +171,7 @@ export default function (bundle: Bundle) {
yield* takeEvery(submissionChangeCurrentSubmissionId, function* ({payload}) {
const submissionId = yield* appSelect(state => state.submission.currentSubmissionId);
if (null === submissionId) {
yield* call(quickAlgoLibraryResetAndReloadStateSaga, app);
yield* call(quickAlgoLibraryResetAndReloadStateSaga);
yield* put(stepperClearError());
}
});
Expand Down
47 changes: 13 additions & 34 deletions frontend/task/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,12 +432,9 @@ function* handleLibrariesEventListenerSaga(app: App) {

yield stepperContext.quickAlgoCallsExecutor(module, method, args, () => {
log.getLogger('task').debug('exec done, update task state');
const context = quickAlgoLibraries.getContext(null, state.environment);
if (context) {
const contextState = getCurrentImmerState(context.getInnerState());
log.getLogger('task').debug('get new state', contextState);
app.dispatch(taskUpdateState(contextState));
}
const contextState = quickAlgoLibraries.getLibrariesInnerState(state.environment);
log.getLogger('task').debug('get new state', contextState);
app.dispatch(taskUpdateState(contextState));
});
});
}
Expand Down Expand Up @@ -541,7 +538,7 @@ function* taskUpdateCurrentTestIdSaga(app: App, {payload}) {

// Save context state for the test we have just left
if (context && !payload.recreateContext && null !== state.task.previousTestId) {
const currentState = getCurrentImmerState(context.getInnerState());
const currentState = quickAlgoLibraries.getLibrariesInnerState(state.environment);
yield* put(updateTestContextState({testId: state.task.previousTestId, contextState: currentState}));
}

Expand All @@ -563,16 +560,8 @@ function* taskUpdateCurrentTestIdSaga(app: App, {payload}) {

if (!payload.withoutContextState) {
const contextState = state.task.taskTests[state.task.currentTestId]?.contextState;
if (null !== contextState && undefined !== contextState) {
const currentTest = selectCurrentTestData(state);
log.getLogger('task').debug('[taskUpdateCurrentTestIdSaga] reload current test', currentTest, contextState);
context.resetAndReloadState(currentTest, state, contextState);
} else {
const currentTest = selectCurrentTestData(state);
log.getLogger('task').debug('[taskUpdateCurrentTestIdSaga] reload current test without state', currentTest);
context.resetAndReloadState(currentTest, state);
}

yield* call(quickAlgoLibraryResetAndReloadStateSaga, contextState);
log.getLogger('task').debug('[taskUpdateCurrentTestIdSaga] reload current test', contextState);
yield* put({type: QuickAlgoLibrariesActionType.QuickAlgoLibrariesRedrawDisplay});
}
}
Expand Down Expand Up @@ -822,7 +811,7 @@ export default function (bundle: Bundle) {
Codecast.runner.stop();
}
yield* call(clearSourceHighlightSaga);
yield* call(quickAlgoLibraryResetAndReloadStateSaga, app);
yield* call(quickAlgoLibraryResetAndReloadStateSaga);
log.getLogger('task').debug('put task reset done to true');
yield* put(taskResetDone(true));
});
Expand Down Expand Up @@ -925,11 +914,7 @@ export default function (bundle: Bundle) {
app.recordApi.onStart(function* (init) {
const state = yield* appSelect();
init.testId = state.task.currentTestId;
const context = quickAlgoLibraries.getContext(null, 'main');
if (context) {
const currentState = getCurrentImmerState(context.getInnerState());
init.contextState = currentState;
}
init.contextState = quickAlgoLibraries.getLibrariesInnerState(state.environment);
});

app.replayApi.on('start', function*(replayContext: ReplayContext, event) {
Expand All @@ -938,7 +923,7 @@ export default function (bundle: Bundle) {
yield* put(updateCurrentTestId({testId, withoutContextState: !!contextState}));
}
if (contextState) {
yield* call(quickAlgoLibraryResetAndReloadStateSaga, app, contextState);
yield* call(quickAlgoLibraryResetAndReloadStateSaga, contextState);
}
});

Expand Down Expand Up @@ -999,7 +984,7 @@ export default function (bundle: Bundle) {

const context = quickAlgoLibraries.getContext(null, 'main');
if (context && (!quick || (instant.event && -1 !== ['compile.success'].indexOf(instant.event[1])) || hasChangedLevel || hasChangedTest)) {
yield* call(quickAlgoLibraryResetAndReloadStateSaga, app, taskData && taskData.state ? taskData.state : null);
yield* call(quickAlgoLibraryResetAndReloadStateSaga, taskData && taskData.state ? taskData.state : null);
log.getLogger('replay').debug('DO RESET DISPLAY');
yield* put({type: QuickAlgoLibrariesActionType.QuickAlgoLibrariesRedrawDisplay});
}
Expand Down Expand Up @@ -1032,16 +1017,10 @@ export default function (bundle: Bundle) {
})
});

app.stepperApi.onInit(function* (stepperState: StepperState, state: AppStore) {
const currentTest = selectCurrentTestData(state);

log.getLogger('task').debug('stepper init, current test', currentTest, state.environment);

const context = quickAlgoLibraries.getContext(null, state.environment);
context.resetAndReloadState(currentTest, state);
app.stepperApi.onInit(function* () {
log.getLogger('task').debug('stepper init');
yield* call(quickAlgoLibraryResetAndReloadStateSaga);
yield* put({type: QuickAlgoLibrariesActionType.QuickAlgoLibrariesRedrawDisplay});

stepperState.contextState = getCurrentImmerState(context.getInnerState());
});
});
}
29 changes: 29 additions & 0 deletions frontend/task/libs/debug/DebugLibView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, {useEffect, useRef} from "react";
import {useAppSelector} from '../../../hooks';
import {DebugLibState} from './debug_lib';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faChevronRight} from '@fortawesome/free-solid-svg-icons/faChevronRight';

export function DebugLibView() {
const taskState: DebugLibState = useAppSelector(state => state.task.state?.debug);
const containerRef = useRef<HTMLDivElement>();

useEffect(() => {
containerRef.current.scrollTop = containerRef.current.scrollHeight;
}, [taskState?.linesLogged]);

if (!taskState?.linesLogged?.length) {
return null;
}

return (
<div className="debug-lib-container" ref={containerRef}>
{taskState?.linesLogged.map((line, lineIndex) =>
<div className="debug-lib-line" key={lineIndex}>
<FontAwesomeIcon icon={faChevronRight}/>
<span>{line}</span>
</div>
)}
</div>
);
}
Loading