Skip to content

Instantly share code, notes, and snippets.

@cowboyd
Last active October 13, 2022 18:09
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/f36637b7de582a5df9a3fe5474dcbe3b to your computer and use it in GitHub Desktop.
Save cowboyd/f36637b7de582a5df9a3fe5474dcbe3b to your computer and use it in GitHub Desktop.
Scope resource for managing concurrency in effection
export interface ScopeOptions {
maxConcurrency: number;
}
export interface Scope {
(operation: Operation<T>): Operation<void>;
}
export function createScope(options: ScopeOptions): Operation<Scope> {
let { maxConcurrency = Infinity } = options;
let tasks = new Set<Task>();
let buffer = [] as Task[];
let queue = createQueue<Operation>;
return {
name: 'Scope',
*init(scope) {
yield spawn(queue.forEach(operation) {
yield spawn(function*() {
let task = yield spawn(operation);
tasks.add(task);
try {
yield task;
} finally {
tasks.delete(task);
if (tasks.size() < maxConcurrency && buffer.length > 0) {
queue.send(buffer.pop());
}
}, { scope });
});
return function* enqueue(operation) {
if (tasks.size() < maxConcurrency) {
queue.send(operation)
} else {
buffer.unshift(operation);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment