workerd icon indicating copy to clipboard operation
workerd copied to clipboard

Support discriminated unions for queue message batches

Open cloudkite opened this issue 1 year ago • 0 comments

When a worker is a consumer for multiple queues its not possible with the existing types to make the message body type depend on the name of the queue.

Changing the queue name to be generic would allow creating a discriminated union type for different message batches

- export interface MessageBatch<Body = unknown> {
+ export interface MessageBatch<Body = unknown, Name = string> {
   readonly messages: readonly Message<Body>[];
-  readonly queue: string;
+  readonly queue: Name;
   retryAll(options?: QueueRetryOptions): void;
   ackAll(): void;
 }

Which then enables:

type Batch = 
   | MessageBatch<{ foo: number }, "queue-1">
   | MessageBatch<{ bar: number }, "queue-2">

export default class extends WorkerEntrypoint {
  async queue(_batch: Batch) {
      switch (batch.queue) {
        case "queue-1": {
          // message.body is typed as { foo: number } here
          break;
        }
        case "queue-2": {
          // message.body is typed as { bar: number } here
          break;
        }
    }
  }
}

cloudkite avatar Sep 24 '24 22:09 cloudkite