diff --git a/src/examples/task.ts b/src/examples/task.ts index 7ca6955129de1402051380c3f2daf564d9a60618..1378785ce863bc7488761cce480b3bcde80364d9 100644 --- a/src/examples/task.ts +++ b/src/examples/task.ts @@ -28,9 +28,9 @@ function messageTree(root: Progress.Node, prefix = ''): string { function createTask<T>(delayMs: number, r: T): Task<T> { return Task.create('delayed value ' + r, async ctx => { - ctx.update('Processing delayed... ' + r, true); + ctx.update(`Processing delayed ${r} after ${delayMs}ms`, true); await Scheduler.delay(delayMs); - if (ctx.shouldUpdate) await ctx.update({ message: 'hello from delayed... ' }); + if (ctx.shouldUpdate) await ctx.update({ message: `hello from delayed ${r} ${delayMs}` }); return r; }, () => console.log('On abort called ' + r)); } @@ -63,7 +63,7 @@ export function testTree() { const r = await c1 + await c2 + await c3; if (ctx.shouldUpdate) await ctx.update({ message: 'Almost done...' }); return r + 1; - }); + }, () => console.log('On abort O')); } export type ChunkedState = { i: number, current: number, total: number } @@ -115,7 +115,7 @@ async function test() { // const r = await Run(testTree(), abortingObserver, 250); // console.log(r); - const m = await ms({ i: 10 }).run(logP); + const m = await testTree().run(abortingObserver, 50); console.log(m); } catch (e) { console.error(e); diff --git a/src/mol-task/execution/observable.ts b/src/mol-task/execution/observable.ts index f16d04025f754f09879fd0c4e7c98da69290cdf9..c4bed0acf2277f24eca600e1c20ded27f3fe284d 100644 --- a/src/mol-task/execution/observable.ts +++ b/src/mol-task/execution/observable.ts @@ -10,7 +10,7 @@ import { Progress } from './progress' import { now } from '../../mol-util/now'; import { Scheduler } from '../util/scheduler' import { UserTiming } from '../util/user-timing' -import { isProductionMode } from '../../mol-util/debug' +import { isDebugMode } from '../../mol-util/debug' interface ExposedTask<T> extends Task<T> { f: (ctx: RuntimeContext) => Promise<T>, @@ -101,6 +101,8 @@ async function execute<T>(task: ExposedTask<T>, ctx: ObservableRuntimeContext) { return ret; } catch (e) { if (Task.isAbort(e)) { + ctx.isAborted = true; + // wait for all child computations to go thru the abort phase. if (ctx.node.children.length > 0) { await new Promise(res => { ctx.onChildrenFinished = res; }); @@ -109,7 +111,7 @@ async function execute<T>(task: ExposedTask<T>, ctx: ObservableRuntimeContext) { task.onAbort(); } } - if (!isProductionMode) console.error(e); + if (isDebugMode) console.error(e); throw e; } } @@ -147,6 +149,8 @@ class ObservableRuntimeContext implements RuntimeContext { isExecuting = true; lastUpdatedTime = 0; + isAborted?: boolean; + node: Progress.Node; info: ProgressInfo; @@ -155,6 +159,7 @@ class ObservableRuntimeContext implements RuntimeContext { private checkAborted() { if (this.info.abortToken.abortRequested) { + this.isAborted = true; abort(this.info); } } @@ -220,7 +225,7 @@ class ObservableRuntimeContext implements RuntimeContext { // need to catch the error here because otherwise // promises for running child tasks in a tree-like computation // will get orphaned and cause "uncaught error in Promise". - return void 0 as any; + if (this.isAborted) return void 0 as any; } throw e; } finally {