Skip to content

Instantly share code, notes, and snippets.

@cowboyd
Last active February 22, 2023 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cowboyd/1ffcf43b60cf60c4e56edaa261c96eb4 to your computer and use it in GitHub Desktop.
Save cowboyd/1ffcf43b60cf60c4e56edaa261c96eb4 to your computer and use it in GitHub Desktop.
all() and race() implementations with effection v3 architecture
import type { Operation } from "./types.ts";
import { action, resource, spawn } from "./mod.ts";
export function all<T>(operations: Operation<T>[]): Operation<T[]> {
return resource(function* All(provide) {
let scope = yield* useScope();
let tasks = operations.map(op => scope.run(() => op));
let results = yield* map(tasks, task => task);
yield* provide(results);
});
}
export function race<T>(operations: Operation<T>[]): Operation<T> {
return resource(function* Race(provide) {
let scope = yield* useScope();
let tasks = operations.map(op => scope.run(() => op));
let winner = yield* action<T>(function*(resolve) {
for (let task of tasks) {
yield* spawn(function*() {
resolve(yield* task);
});
}
});
// halt losers in parallel
for (let task of tasks) {
if (task !== winner) {
yield* spawn(() => task.halt());
}
}
yield* provide(winner);
});
}
function* map<T, R>(values: T[], each: (value: T) => Operation<R>): Operation<R[]> {
let results: R[] = [];
for (let value of values) {
results.push(yield* each(value));
}
return results;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment