UNPKG

@ceramicnetwork/core

Version:

Typescript implementation of the Ceramic protocol

63 lines 2.28 kB
import { noop, TaskQueue } from '../ancillary/task-queue.js'; import { ServiceMetrics as Metrics } from '@ceramicnetwork/observability'; const NAMED_TASK_QUEUE_SIZE = 'named_task_queue_size'; const NAMED_TASK_QUEUE_RUN = 'named_task_queue_run'; const NAMED_TASK_QUEUE_ADD = 'named_task_queue_add'; const NAMED_TASK_QUEUE_LARGE_SIZE = 'named_task_queue_large_size'; const LARGE_QUEUE_THRESHOLD = process.env.LARGE_QUEUE_THRESHOLD || 50; export class NamedTaskQueue { constructor(onError = noop, lanes = new Map()) { this.onError = onError; this.lanes = lanes; } queue(name) { const found = this.lanes.get(name); if (found) { return found; } else { const queue = new TaskQueue(1, this.onError.bind(this)); this.lanes.set(name, queue); return queue; } } remove(name) { const found = this.lanes.get(name); if (found && found.size === 0) { this.lanes.delete(name); } } run(name, task) { const queue = this.queue(name); Metrics.observe(NAMED_TASK_QUEUE_SIZE, queue.size, { method: 'run' }); Metrics.count(NAMED_TASK_QUEUE_RUN, 1); if (queue.size > LARGE_QUEUE_THRESHOLD) { Metrics.observe(NAMED_TASK_QUEUE_LARGE_SIZE, queue.size, { name: name, method: 'run' }); } return queue.run(task).finally(() => { this.remove(name); }); } add(name, task) { const queue = this.queue(name); Metrics.observe(NAMED_TASK_QUEUE_SIZE, queue.size, { method: 'add' }); Metrics.count(NAMED_TASK_QUEUE_ADD, 1, { name: name }); if (queue.size > LARGE_QUEUE_THRESHOLD) { Metrics.observe(NAMED_TASK_QUEUE_LARGE_SIZE, queue.size, { name: name, method: 'add' }); } queue.add(() => task(), () => this.remove(name)); } async onIdle() { const lanes = Array.from(this.lanes.values()); await Promise.all(lanes.map((lane) => lane.onIdle())); } async close() { await this.onIdle(); this.pause(); } pause() { const lanes = Array.from(this.lanes.values()); lanes.map((l) => l.pause()); } } //# sourceMappingURL=named-task-queue.js.map