Skip to content

Commit

Permalink
Switch thread in Python
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastienTainon committed May 13, 2024
1 parent 3fed1e4 commit ceeb7e2
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 41 deletions.
19 changes: 16 additions & 3 deletions frontend/stepper/abstract_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default abstract class AbstractRunner {
}

public initCodes(codes, availableBlocks = null) {

this.threads = [];
}

public stop() {
Expand Down Expand Up @@ -120,21 +120,34 @@ export default abstract class AbstractRunner {
}

public createNewThread(threadData: any) {
log.getLogger('multithread').debug('[multithread] default create new thread');
}

public registerNewThread(threadData: any) {
this.threads.push(threadData);
this.currentThreadId = this.threads.length - 1;
log.getLogger('multithread').debug('[multithread] register new thread', threadData, threadData.length);
this.threads.push([...threadData]);
// this.currentThreadId = this.threads.length - 1;
}

public getAllThreads() {
log.getLogger('multithread').debug('[multithread] all threads', [...this.threads]);
return this.threads;
}

public saveCurrentThreadData(threadData: any) {
log.getLogger('multithread').debug('[multithread] save thread data', {threadId: this.currentThreadId, threadData});
this.threads[this.currentThreadId] = threadData;
}

public getCurrentThreadId() {
return this.currentThreadId;
}

public swapCurrentThreadId(newThreadId: number) {
}

public currentThreadFinished() {
this.threads.splice(this.currentThreadId, 1);
log.getLogger('multithread').debug('[multithread] new threads', [...this.threads]);
}
}
1 change: 1 addition & 0 deletions frontend/stepper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,7 @@ function* stepperStepSaga(app: App, action) {
try {
taskContext.infos.checkEndCondition(taskContext, true);
} catch (executionResult: unknown) {
log.getLogger('stepper').debug('end condition result', {executionResult});
// Update test context state with latest data from checkEndCondition
const contextState = quickAlgoLibraries.getLibrariesInnerState(state.environment);
yield* put(taskUpdateState(contextState));
Expand Down
5 changes: 1 addition & 4 deletions frontend/stepper/js/blockly_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ export default class BlocklyRunner extends AbstractRunner {
};

initCodes(codes, availableBlocks) {
super.initCodes(codes, availableBlocks);
log.getLogger('blockly_runner').debug('init codes', codes);
this.delayFactory.destroyAll();
this.interpreters = [];
Expand Down Expand Up @@ -672,8 +673,4 @@ export default class BlocklyRunner extends AbstractRunner {
log.getLogger('multithread').debug('[multithread] change current thread', stack);
this.interpreters[0].stateStack = stack;
}

public currentThreadFinished() {
this.threads.splice(this.currentThreadId, 1);
}
}
74 changes: 46 additions & 28 deletions frontend/stepper/python/python_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ export default class PythonRunner extends AbstractRunner {
};

checkArgs(name, generatorName, blockName, args) {
console.log('check function args', {name});
let msg = '';

// Check the number of arguments corresponds to a variant of the function
Expand Down Expand Up @@ -270,19 +269,18 @@ export default class PythonRunner extends AbstractRunner {

try {
const suspendableFn = () => {
console.log('call to suspendable');
return val.tp$call(args);
};
let promise = this._debugger.asyncToPromise(suspendableFn, null, this._debugger);
promise.then((response) => {
console.log('thened', response);
this._debugger.success.bind(this._debugger);
}, (error) => {
console.log('errored', error);
this._debugger.error.bind(this._debugger);

this.context.onError(error + "\n");
});
// promise.then((response) => {
// console.log('thened', response);
// this._debugger.success.bind(this._debugger);
// }, (error) => {
// console.log('errored', error);
// this._debugger.error.bind(this._debugger);
//
// this.context.onError(error + "\n");
// });

return promise;
} catch (e) {
Expand Down Expand Up @@ -432,6 +430,8 @@ export default class PythonRunner extends AbstractRunner {
}

public initCodes(codes, availableBlocks) {
super.initCodes(codes, availableBlocks);

// For reportValue in Skulpt.
window.currentPythonRunner = this;

Expand Down Expand Up @@ -463,7 +463,6 @@ export default class PythonRunner extends AbstractRunner {
// susp_handlers['*'] = this._debugger.suspension_handler.bind(this);
let promise = this._debugger.asyncToPromise(this._asyncCallback.bind(this), null, this._debugger);
promise.then((response) => {
console.log('on final response');
// this._debugger.success.bind(this._debugger);
}, (error) => {
// this._debugger.error.bind(this._debugger);
Expand All @@ -484,12 +483,8 @@ export default class PythonRunner extends AbstractRunner {
runStep(quickAlgoCallsExecutor, noInteractive = false) {
this.quickAlgoCallsExecutor = quickAlgoCallsExecutor;

console.log('check event listeners before running step', {running: this._isRunning, progress: this._stepInProgress});
console.log('start running step');

return new Promise((resolve, reject) => {
this.stepMode = !noInteractive;
console.log('step', {running: this._isRunning, progress: this._stepInProgress});
if (this._isRunning && !this._stepInProgress) {
this.step(resolve, reject);
}
Expand All @@ -505,7 +500,7 @@ export default class PythonRunner extends AbstractRunner {
})
}

reportValue (origValue) {
reportValue(origValue) {
return origValue;
}

Expand Down Expand Up @@ -562,7 +557,6 @@ export default class PythonRunner extends AbstractRunner {
step(resolve, reject) {
log.getLogger('python_runner').debug('continue step', resolve, reject, this._resetCallstackOnNextStep);
this._resetCallstack();
console.log('change step in progress', {previous: this._stepInProgress, next: true});
this._stepInProgress = true;

this.realStep(resolve, reject);
Expand All @@ -583,7 +577,6 @@ export default class PythonRunner extends AbstractRunner {
// Used in Skulpt
_onStepSuccess(callback) {
// If there are still timeouts, there's still a step in progress
console.log('change step on step success', {previous: this._stepInProgress, next: !!this._timeouts.length});
this._stepInProgress = !!this._timeouts.length;
this._continue();

Expand Down Expand Up @@ -736,23 +729,48 @@ export default class PythonRunner extends AbstractRunner {
});
}

public createNewThread(threadData) {
const promise = threadData();
log.getLogger('multithread').debug('create new thread -> promise', promise);
public createNewThread(promiseCreator) {
log.getLogger('multithread').debug('[multithread] create new thread -> promise', promiseCreator);

// Save previous state
this.saveCurrentThreadData([...this._debugger.suspension_stack]);

// Execute promise to get new state
const promise = promiseCreator();

this.registerNewThread(promise);
// Add main suspension stack before this one, so that when this thread finishes, the program does not finishes
const mainThreadStack = this.getAllThreads()[0];

const newSuspensionStack = [
...mainThreadStack,
];

const lastSuspension = this._debugger.suspension_stack[0];
newSuspensionStack[newSuspensionStack.length - 1] = {
...newSuspensionStack[newSuspensionStack.length - 1],
child: lastSuspension,
};
newSuspensionStack.push(lastSuspension);

// Register new thread
this.registerNewThread(newSuspensionStack);

// Restore previous state, since we haven't switched yet to the new thread
this._debugger.suspension_stack = this.getAllThreads()[this.currentThreadId];

promise
.then((aaa) => {
log.getLogger('multithread').debug('end of thread', aaa);
.then(() => {
log.getLogger('multithread').debug('[multithread] end of thread');
this.currentThreadFinished();
})
}

public swapCurrentThreadId(newThreadId: number) {
this.saveCurrentThreadData([...this._debugger.suspension_stack]);
this.currentThreadId = newThreadId;
const threads = this.getAllThreads();
const stack = threads[newThreadId];
console.log('change current thread', stack);

const suspensionStack = threads[newThreadId];
log.getLogger('multithread').debug('[multithread] change current thread', suspensionStack);
this._debugger.suspension_stack = suspensionStack;
}
}
2 changes: 1 addition & 1 deletion frontend/task/libs/quickalgo_library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ export abstract class QuickAlgoLibrary {
const threads = this.runner.getAllThreads();
let currentThreadId = this.runner.getCurrentThreadId();
currentThreadId = (currentThreadId + 1) % threads.length;
log.getLogger('multithread').debug('[multithread] schedule thread', {threads, currentThreadId});
log.getLogger('multithread').debug('[multithread] schedule thread', {threads: [...threads], currentThreadId});
this.runner.swapCurrentThreadId(currentThreadId);
}
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.16",
"@france-ioi/persistent-c": "11.2.10",
"@france-ioi/skulpt": "1.3.10",
"@france-ioi/skulpt": "1.3.11",
"@hedgedoc/html-to-react": "^1.4.6",
"@reduxjs/toolkit": "^1.7.1",
"@taquito/michel-codec": "^17.0.0",
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1370,10 +1370,10 @@
immutable "^3.7.6"
text-encoding-utf-8 "^1.0.1"

"@france-ioi/[email protected].10":
version "1.3.10"
resolved "https://npm.pkg.github.com/download/@France-ioi/skulpt/1.3.10/934e5404b802a902147e737c258ce384b69a0922#934e5404b802a902147e737c258ce384b69a0922"
integrity sha512-cckVPAXBP/UjFzE2rFkItbWNWCguk7AiuWfuJUcfXtOqBOnI+BUk4HcAMtTZ3gSIC1tL58CQSw7OMIdRqYB2xg==
"@france-ioi/[email protected].11":
version "1.3.11"
resolved "https://npm.pkg.github.com/download/@France-ioi/skulpt/1.3.11/8e3eee7f0d4ce553ef1d70ac95ea26884ce9a46c#8e3eee7f0d4ce553ef1d70ac95ea26884ce9a46c"
integrity sha512-7+VtDBHZVyiddlK9RaxeQyjj8rVa7PGkxhriTHJ6aUX4airOY+VDuc6S1PVyFBMb8ACbPazMnfv6HfCUeoXAtQ==
dependencies:
jsbi "^3.1.4"
uuid "^8.2.0"
Expand Down

0 comments on commit ceeb7e2

Please sign in to comment.