Skip to content
Snippets Groups Projects
Commit 50ee781d authored by David Sehnal's avatar David Sehnal
Browse files

task api

parent 0442d953
No related branches found
No related tags found
No related merge requests found
......@@ -12,6 +12,10 @@ async function test() {
console.log(r);
}
function delay(ms: number) {
return new Promise(r => setTimeout(r, ms));
}
function messageTree(root: Progress.Node, prefix = ''): string {
if (!root.children.length) return `${prefix}${root.progress.message}`;
......@@ -20,25 +24,30 @@ function messageTree(root: Progress.Node, prefix = ''): string {
return `${prefix}${root.progress.message}\n${subTree.join('\n')}`;
}
function createTask<T>(delay: number, r: T): Task<T> {
function createTask<T>(delayMs: number, r: T): Task<T> {
return Task.create('delayed', async ctx => {
await new Promise(r => setTimeout(r, delay));
if (ctx.requiresUpdate) await ctx.update({ message: 'hello from delayed...' });
ctx.updateProgress('Processing delayed... ' + r);
await delay(delayMs);
if (ctx.needsYield) await ctx.yield({ message: 'hello from delayed... ' + r });
return r;
});
}
async function testObs() {
const t = Task.create('test o', async ctx => {
await new Promise(r => setTimeout(r, 250));
if (ctx.requiresUpdate) await ctx.update({ message: 'hi! 1' });
await new Promise(r => setTimeout(r, 125));
if (ctx.requiresUpdate) await ctx.update({ message: 'hi! 2' });
await new Promise(r => setTimeout(r, 250));
if (ctx.requiresUpdate) await ctx.update({ message: 'hi! 3' });
const r = await ctx.runChild({ message: 'Running child!' }, createTask(250, 100));
if (ctx.requiresUpdate) await ctx.update({ message: 'Almost done...' });
await delay(250);
if (ctx.needsYield) await ctx.yield({ message: 'hi! 1' });
await delay(125);
if (ctx.needsYield) await ctx.yield({ message: 'hi! 2' });
await delay(250);
if (ctx.needsYield) await ctx.yield('hi! 3');
ctx.updateProgress('Running children...');
const c1 = ctx.runChild(createTask(250, 1));
const c2 = ctx.runChild(createTask(500, 2));
const c3 = ctx.runChild(createTask(750, 3));
const r = await c1 + await c2 + await c3;
if (ctx.needsYield) await ctx.yield({ message: 'Almost done...' });
return r + 1;
});
const r = await Run(t, p => console.log(messageTree(p.root)), 250);
......
......@@ -116,20 +116,26 @@ class ObservableRuntimeContext implements RuntimeContext {
}
}
get requiresUpdate(): boolean {
get needsYield(): boolean {
this.checkAborted();
return now() - this.info.lastUpdated > this.info.updateRateMs;
}
private setProgress(update: Partial<RuntimeContext.ProgressUpdate>) {
private setProgress(update?: string | Partial<RuntimeContext.ProgressUpdate>) {
this.checkAborted();
if (!update) return;
const progress = this.node.progress;
if (typeof update.canAbort !== 'undefined') progress.canAbort = update.canAbort;
if (typeof update.current !== 'undefined') progress.current = update.current;
if (typeof update.isIndeterminate !== 'undefined') progress.isIndeterminate = update.isIndeterminate;
if (typeof update.max !== 'undefined') progress.max = update.max;
if (typeof update.message !== 'undefined') progress.message = update.message;
if (typeof update === 'string') {
progress.message = update;
} else {
if (typeof update.canAbort !== 'undefined') progress.canAbort = update.canAbort;
if (typeof update.current !== 'undefined') progress.current = update.current;
if (typeof update.isIndeterminate !== 'undefined') progress.isIndeterminate = update.isIndeterminate;
if (typeof update.max !== 'undefined') progress.max = update.max;
if (typeof update.message !== 'undefined') progress.message = update.message;
}
}
private resume = () => {
......@@ -137,7 +143,11 @@ class ObservableRuntimeContext implements RuntimeContext {
this.lastScheduledTime = now();
}
update(progress: Partial<RuntimeContext.ProgressUpdate>): Promise<void> {
updateProgress(progress?: string | Partial<RuntimeContext.ProgressUpdate>) {
this.setProgress(progress);
}
yield(progress?: string | Partial<RuntimeContext.ProgressUpdate>): Promise<void> {
this.isExecuting = false;
this.setProgress(progress);
this.info.lastUpdated = now();
......@@ -146,7 +156,7 @@ class ObservableRuntimeContext implements RuntimeContext {
return ImmediateScheduler.last(this.resume);
}
async runChild<T>(progress: Partial<RuntimeContext.ProgressUpdate>, task: Task<T>): Promise<T> {
async runChild<T>(task: Task<T>, progress?: string | Partial<RuntimeContext.ProgressUpdate>): Promise<T> {
this.setProgress(progress);
const node: Progress.Node = { progress: defaultProgress(this.info.taskId, task), children: [] };
const children = this.node.children as Progress.Node[];
......
......@@ -7,12 +7,13 @@
import Task from '../task'
interface RuntimeContext {
readonly requiresUpdate: boolean,
readonly needsYield: boolean,
updateProgress(progress: string | Partial<RuntimeContext.ProgressUpdate>): void,
// Idiomatic usage:
// if (ctx.requiresUpdate) await ctx.update({ ... });
update(progress: Partial<RuntimeContext.ProgressUpdate>): Promise<void>,
// if (ctx.needsYield) await ctx.yield({ ... });
yield(progress?: string | Partial<RuntimeContext.ProgressUpdate>): Promise<void>,
// Force the user to pass the progress so that the progress tree can be kept in a "good state".
runChild<T>(progress: Partial<RuntimeContext.ProgressUpdate>, task: Task<T>): Promise<T>
runChild<T>(task: Task<T>, progress?: string | Partial<RuntimeContext.ProgressUpdate>): Promise<T>
}
namespace RuntimeContext {
......
......@@ -10,9 +10,10 @@ import RuntimeContext from './runtime-context'
const voidPromise = Promise.resolve(void 0);
class SynchronousRuntimeContext implements RuntimeContext {
requiresUpdate: boolean = false;
update(progress: Partial<RuntimeContext.ProgressUpdate>): Promise<void> { return voidPromise; }
runChild<T>(progress: Partial<RuntimeContext.ProgressUpdate>, task: Task<T>): Promise<T> { return ExecuteSynchronous(task); }
needsYield: boolean = false;
updateProgress(progress: string | Partial<RuntimeContext.ProgressUpdate>): void { }
yield(progress?: string | Partial<RuntimeContext.ProgressUpdate>): Promise<void> { return voidPromise; }
runChild<T>(task: Task<T>, progress?: string | Partial<RuntimeContext.ProgressUpdate>): Promise<T> { return ExecuteSynchronous(task); }
}
const SyncRuntimeInstance = new SynchronousRuntimeContext();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment