Gathering detailed insights and metrics for ticket-queue
Gathering detailed insights and metrics for ticket-queue
Gathering detailed insights and metrics for ticket-queue
Gathering detailed insights and metrics for ticket-queue
A ticket-based queue system to synchronize based on ticket acquisition order
npm install ticket-queue
Typescript
Module System
Min. Node Version
Node Version
NPM Version
73.7
Supply Chain
98.5
Quality
83.7
Maintenance
100
Vulnerability
100
License
TypeScript (100%)
Total Downloads
311
Last Day
2
Last Week
15
Last Month
311
Last Year
311
MIT License
12 Commits
1 Branches
1 Contributors
Updated on Jun 24, 2025
Latest Version
0.1.3
Package Id
ticket-queue@0.1.3
Unpacked Size
67.69 kB
Size
13.41 kB
File Count
27
NPM Version
11.3.0
Node Version
24.2.0
Published on
Jun 24, 2025
Cumulative downloads
Total Downloads
Last Day
0%
2
Compared to previous day
Last Week
-6.3%
15
Compared to previous week
Last Month
0%
311
Compared to previous month
Last Year
0%
311
Compared to previous year
1
4
[!NOTE] Node.js >= v24 is highly recommended since it adds Explicit Resource Management
A ticket-based first-in-first-out queue. Instead of using a single blocking acquire()
function, a ticket queue uses a non-blocking acquireTicket()
function that determines the FIFO order for later blocking waitForFirst(ticket)
or waitForFirstAndRemove(ticket)
calls.
In other words, a function can get a ticket without waiting or blocking, perform some work (without blocking any parallel work), then later wait for their turn using their ticket. Turn order is decided by ticket acquisition order.
Tickets are Disposable (see Explicit Resource Management) which allows tickets to automatically get removed from the queue once they go out of scope—including if the code errors. Explicit resource management is not required but is highly recommended since it avoids stalling the ticket queue!
[!WARN] This is an ESM-only package. If you're using Common.js you will have to figure out your own way to import it. Node.js is the only actually-actively maintained runtime (I don't have time for others 😔) but I will accept issues or PRs relating to other runtimes (bug reports, fixes, and CI support are welcome!)
1# Node.js -> Pick your favorite: 2npm i ticket-queue 3npx jsr add @atorasuunva/ticket-queue 4pnpm i ticket-queue 5pnpm i jsr:@atorasuunva/ticket-queue 6 7# Deno 8deno add jsr:@atorasuunva/ticket-queue 9 10# Bun 11bunx jsr add @atorasuunva/ticket-queue
1import { TicketQueue } from 'ticket-queue' 2 3const ticketQueue = new TicketQueue() 4 5// We have some event where messages need to be sent in order, but the work to prepare the messages can take varying amounts of time and can be done in parallel with other events. 6async function onEvent(name) { 7 using ticket = ticketQueue.acquireTicket() 8 9 // Perform some work that can take a varying amount of time 10 await doSomeWork() 11 12 // Wait for our ticket to be first in the queue 13 await ticketQueue.waitForFirst(ticket) 14 15 // Now we are first in the queue and can proceed with the next step 16 await sendMessage(name) 17 18 // Once `sendMessage()` completes, we allow explicit resource management to dispose of the ticket, removing it from the queue and allowing the next ticket-holder to continue 19} 20 21onEvent('A') 22onEvent('B') 23onEvent('C') 24onEvent('D') 25 26// Every `onEvent()` can `doSomeWork()` in parallel without waiting on someone else 27// And no matter how long each `doSomeWork()` takes, the order of `sendMessage()` calls will be 28// A 29// B 30// C 31// D
Node.js v24 introduces explicit resource management. Using using
guarantees that tickets are always disposed (and removed from the queue) when they go out of scope. Without using
you are responsible in making sure your tickets are removed or you will stall the ticket queue. Node.js < v24 may work but you will have to try {} finally {}
after every single acquireTicket()
call.
1const ticketQueue = new TicketQueue() 2 3// This is the recommended way to use ticket-queue 4async function alsoCorrectlyRemovesTicket() { 5 // `using` for explicit resource management 6 using ticket = ticketQueue.acquireTicket() 7 8 await doSomeWork() 9 // Even if `doSomeWork()` rejects, explicit resource management will ensure our ticket is removed from queue when it goes out of scope. We don't have to do any extra work 10 await ticketQueue.waitForFirstAndRemove(ticket) 11 await sendMessage() 12} 13 14// This is OK 15async function correctlyRemovesTicket() { 16 const ticket = ticketQueue.acquireTicket() 17 18 try { 19 await doSomeWork() 20 await ticketQueue.waitForFirstAndRemove(ticket) 21 await sendMessage() 22 } finally { 23 // Even if we use `waitForFirstAndRemove()`, we _must_ handle the event where `doSomeWork()` rejects and prevents `waitForFirstAndRemove() from being called 24 ticket.removeFromQueue() 25 } 26} 27 28// DO NOT DO THIS!!! 29async function stallsQueue() { 30 const ticket = ticketQueue.acquireTicket() 31 32 await doSomeWork() 33 // If `doSomeWork()` rejects, we never wait and remove the ticket and _everyone_ else will have to wait for our ticket to time out. 34 // `ticketTimeout` will prevent the queue from being blocked forever, but it will delay everyone else until the ticket is removed 35 await ticketQueue.waitForFirstAndRemove(ticket) 36 await sendMessage() 37}
TicketQueues come with a 500ms timeout and 3 retries limit by default. If a ticket is at the front of the queue for 500ms without being removed, the TicketQueue automatically moves it to the back of the queue and moves onto the next ticket. The 4th time a ticket times out it is outright removed from the queue without being requeued. This prevents a single ticket never being removed from stalling the queue forever and multiple tickets never being removed making the queue slow.
These limits are configurable if you need a different timeout window or no timeout at all. Beware that disabling the timeout feature will risk a single ticket stalling your queue for everyone, so make sure you always remove tickets (even on exceptions) and never take too long to remove them.
1const ticketQueue = new TicketQueue({ 2 ticketTimeout: 0, // Disables the timeout 3 ticketRetries: 0, // Tickets are immediately removed from the queue when they time out instead of being requeued 4})
No vulnerabilities found.