Skip to content

Ordering and batching: a chat burst in one call

A user sends five chat messages in two seconds: windowBuffer holds the burst, and the handler gets it in order, in one call, instead of five.

Updated View as Markdown

A chat: every conversation must be handled in order, and a slow one must not delay the others. And a guest rarely sends one message. They send three in a row: “Hi!”, “Is breakfast included?”, “And is there parking?”. An assistant that answers each message at once answers three times.

Every conversation is a partition of its own, created by its first message, so its messages stay in order and it waits on nobody else. windowBuffer adds the batching: new messages of a conversation wait until the first of them is two seconds old, and then go to the handler together.

Partition conv-42 on a time axis. The guest sends Hi at 0 seconds, Is breakfast included at 0.4 and And is there parking at 0.9. With windowBuffer 2, the messages wait until the first is two seconds old; at 2 seconds the assistant receives all three in one batch and answers once. Another conversation, conv-7, is not held by conv-42.Partition conv-42 on a time axis. The guest sends Hi at 0 seconds, Is breakfast included at 0.4 and And is there parking at 0.9. With windowBuffer 2, the messages wait until the first is two seconds old; at 2 seconds the assistant receives all three in one batch and answers once. Another conversation, conv-7, is not held by conv-42.
A conversation's burst waits two seconds, then goes as one batch.
// A burst waits 2 seconds, then goes to the handler as one batch.
await queen.queue('chat').config({ windowBuffer: 2 }).create()

// The guest sends three messages in a row.
for (const text of ['Hi!', 'Is breakfast included?', 'And is there parking?']) {
  await queen.queue('chat').partition('conv-42').push([{ data: { text } }])
}

// The assistant answers the whole burst once.
await queen.queue('chat')
  .group('assistant')
  .subscriptionMode('all')
  .batch(10)                          // the handler gets every message of the burst
  .consume(async (messages) => {
    question = messages.map((m) => m.data.text).join(' ')
    console.log(question)             // Hi! Is breakfast included? And is there parking?
  })

The handler ran once, two seconds after the first message, with the three texts.

Why
a conversation comes in bursts, not one message at a time. Waiting a moment gives the assistant the whole question. Each conversation waits only for its own burst, never for the others.

One thing to know: the window ends two seconds after the oldest waiting message, even if the guest keeps typing, so a long burst is answered in parts, every two seconds.

Built from: Queues (windowBuffer), Pop and consume.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close