Skip to content

Instantly share code, notes, and snippets.

@cowboyd
Last active March 29, 2023 16:22
Show Gist options
  • Save cowboyd/fc4786a9e6b8735a8e3714ae7d014b37 to your computer and use it in GitHub Desktop.
Save cowboyd/fc4786a9e6b8735a8e3714ae7d014b37 to your computer and use it in GitHub Desktop.
Beefed up `Scope`
import type { Stream, Task, Operation, Result } from "./types.ts";
export interface Scope extends Operation<void> {
run<T>(operation: () => Operation<T>): Task<T>;
close(): Operation<void>;
created: Stream<Task<unknown>, void>;
enqueued: Stream<Operation<unknown>, void>;
dropped: Stream<Operation<unknown>, void>;
results: Stream<{task: Task<unknown>, result: Result<unknown>}, void>;
}
// spawn is not an instruction, it is a context effect. Where
// a spawn happens, and where its errors are dependent on the "spawn context"
function* spawn<T>(operation: () => Operation<T>): Task<T> {
let scope = yield* SpawnContext;
return scope.run(operation);
}
/* possible spawn contexts */
//default spawn scope does not constrain tasks
//if an error happens, it crashes, but subsequent scopes can override.
createScope({
maxConcurrency: Math.Infinity,
*onResult(result: Result<unknown>, task: Task<unknown>) {
if (!result.ok) {
throw result.error;
}
}
});
//http handler
createScope({
maxCurrency: 1000,
maxQueue: 10_000,
drop: "newest"
})
//click handler with AJAX request
createScope({
maxConcurrency: 1,
drop: "oldest",
});
// file uploader.
createScope({
maxConcurrency: 10,
maxQueue: 10,
*onDrop() {
window.alert('10 files are already waiting to upload');
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment