Hi all!
I have an issue in my extension when running code. I run some code on a kernel through the extension and use the native notification system to let the user know when the code is running and is finished. It works fine unless the code run so fast that it is already executed by the time the code tried to get the response (I think this is the issue). This results in the notification “running…” forever because it never catches the response from the kernel as it’s already been sent.
Below is my code:
current.context.sessionContext.ready.then(async () => {
try {
// Create promise to track success or failure of the request
const delegate = new PromiseDelegate<ReadonlyJSONValue>();
const start = performance.now();
Notification.promise(delegate.promise, {
// Message when the task is pending
pending: { message: 'Running...', options: { autoClose: false }},
// Message when the task finished successfully
success: {
message: (result: any) => `Pipeline execution successful after ${result.delayInSeconds} seconds.`,
options: {
autoClose: 3000
}
},
// Message when the task finished with errors
error: {
message: () => 'Pipeline execution failed. Check error messages in the Log Console.',
options: {
actions: [
{
label: 'Log Console',
callback: () => {
const command = 'pipeline-console:open';
commands.execute(command, {}).catch(reason => {
console.error(
`An error occurred during the execution of ${command}.\n${reason}`
);
});
}
}
],
autoClose: 5000
}
}
});
const future = current.context.sessionContext.session.kernel!.requestExecute({ code: args.code });
// Here, if the execution is too fast, the response has already been sent by the time we try to catch it:
future.onReply = reply => {
const end = performance.now();
const delay = end - start;
const delayInSeconds = (delay / 1000).toFixed(1);
if (reply.content.status === "ok") {
delegate.resolve({ delayInSeconds });
} else {
delegate.reject({ delayInSeconds });
}
};
future.onIOPub = msg => {
if (msg.header.msg_type === 'stream') {
// Handle stream messages if necessary
} else if (msg.header.msg_type === 'error') {
// Handle error messages
const errorMsg = msg as KernelMessage.IErrorMsg;
const errorOutput = errorMsg.content;
console.error(`Received error: ${errorOutput.ename}: ${errorOutput.evalue}`);
}
};
future.onDone = () => {
const end = performance.now();
const delay = end - start;
const delayInSeconds = (delay / 1000).toFixed(1);
delegate.resolve({ delayInSeconds });
};
await future.done;
} catch (error) {
console.error(error);
}
});
So I’m wondering if I’m following the best practice here, or if there is a known solution?
Thanks in advance,
Thibaut