UNPKG

@ydbjs/topic

Version:

YDB Topics client for publish-subscribe messaging. Provides at-least-once delivery, exactly-once publishing, FIFO guarantees, and scalable message processing for unstructured data.

101 lines 2.9 kB
export class AsyncPriorityQueue { paused = false; closed = false; heap = []; pendingShift; pendingResume; get size() { return this.heap.length; } push(value, priority = 0) { if (this.closed) { throw new Error('Queue closed'); } let left = 0; let right = this.heap.length; while (left < right) { let mid = (left + right) >> 1; if (this.heap[mid].priority < priority) { right = mid; } else { left = mid + 1; } } this.heap.splice(left, 0, { value, priority }); if (this.pendingShift && this.heap.length > 0) { const next = this.heap.shift(); const resolve = this.pendingShift; delete this.pendingShift; resolve({ value: next.value, done: false }); } } async next() { if (this.paused) { await new Promise((resolve) => { this.pendingResume = resolve; }); } // Return done if closed and no items to process if (this.closed && this.heap.length === 0) { return { value: undefined, done: true }; } if (this.heap.length > 0) { let next = this.heap.shift(); return { value: next.value, done: false }; } // If we reach here: not closed and no items in heap // Create pending operation to wait for new items return new Promise((resolve) => { this.pendingShift = resolve; }); } pause() { this.paused = true; } resume() { if (!this.paused) { return; } this.paused = false; if (this.pendingResume) { const resolve = this.pendingResume; delete this.pendingResume; resolve(); } } close() { this.closed = true; // Resolve any pending operations with done: true if (this.pendingShift) { let resolve = this.pendingShift; delete this.pendingShift; resolve({ value: undefined, done: true }); } if (this.pendingResume) { let resolve = this.pendingResume; delete this.pendingResume; resolve(); } } dispose() { // Clear the heap to prevent memory leaks this.heap.length = 0; // Close and resolve pending operations this.close(); } async *[Symbol.asyncIterator]() { while (true) { // eslint-disable-next-line no-await-in-loop let { value, done } = await this.next(); if (done) { break; } yield value; } } [Symbol.dispose]() { this.dispose(); } } //# sourceMappingURL=queue.js.map