Skip to content

MQ-1202 Include metrics metadata in queue() handler message batch#6339

Open
KennethRuan wants to merge 1 commit intocloudflare:mainfrom
KennethRuan:kruan/MQ-1202-add-metrics-metadata-to-queue-handler
Open

MQ-1202 Include metrics metadata in queue() handler message batch#6339
KennethRuan wants to merge 1 commit intocloudflare:mainfrom
KennethRuan:kruan/MQ-1202-add-metrics-metadata-to-queue-handler

Conversation

@KennethRuan
Copy link

@KennethRuan KennethRuan commented Mar 16, 2026

Summary

Adds a new metadata property to queue message batches (MessageBatch / QueueEvent), exposing queue metrics with each batch delivered to a worker's queue() handler.

Changes

This PR includes changes to queue.c++ and queue.h to include metrics on each message batch. The metadata contains three metrics from the upstream queue broker worker (backlogCount, backlogBytes, oldestMessageTimestamp). Below is what the generated types will look like:

// NEW
interface MessageBatchMetrics {
  backlogCount: number;
  backlogBytes: number;
  oldestMessageTimestamp: number;
}
// NEW
interface MessageBatchMetadata { 
  metrics: MessageBatchMetrics;
}

interface QueueEvent<Body = unknown> extends ExtendableEvent {
  readonly messages: readonly Message<Body>[];
  readonly queue: string;
  readonly metadata: MessageBatchMetadata;  // NEW FIELD
  retryAll(options?: QueueRetryOptions): void;
  ackAll(): void;
}
interface MessageBatch<Body = unknown> {
  readonly messages: readonly Message<Body>[];
  readonly queue: string;
  readonly metadata: MessageBatchMetadata;  // NEW FIELD
  retryAll(options?: QueueRetryOptions): void;
  ackAll(): void;
}

The new type changes are gated behind a queue_batch_metadata compat flag so that it can be tested internally before release. Additionally, changes were made to http.c++ and http.h so that the Fetcher used for testing can accept an optional metadata argument.

Upstream changes can be found here: https://gitlab.cfdata.org/cloudflare/mq/queue-broker-worker/-/merge_requests/1765

Testing

  • bazel test //src/workerd/api/tests:queue-test@
  • bazel test //src/workerd/api/tests:queue-test@all-compat-flags
  • bazel test //src/workerd/api/tests:queue-metadata-test@
  • bazel test //src/workerd/api/tests:queue-metadata-test@all-compat-flags
  • bazel test //types:test/types/rpc

@KennethRuan KennethRuan requested review from a team as code owners March 16, 2026 20:39
@KennethRuan KennethRuan marked this pull request as draft March 16, 2026 21:02
@KennethRuan KennethRuan marked this pull request as ready for review March 16, 2026 23:59
@jasnell
Copy link
Collaborator

jasnell commented Mar 17, 2026

/bigbonk review this

Copy link
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

Overall this is a solid, well-structured change. The compat flag gating, capnp schema additions, and test coverage are all done correctly. A few items to address:

  • [Medium] backlogCount and backlogBytes would read more naturally as integer types rather than double at the JS API level — consider whether the upstream data truly requires floating-point representation.
  • [Low] QueueEvent::getMetadata() and QueueController::getMetadata() return MessageBatchMetadata by value, creating a copy on every property access. For a struct of three doubles this is cheap, but worth noting for consistency with lazy-evaluation patterns used for messages.
  • [Low] The Fetcher::queue() TS override shows metadata?: MessageBatchMetadata unconditionally, meaning the type signature is visible in tooling even for workers without the queue_batch_metadata flag. This is fine for a testing API, but worth confirming it's intentional.
  • [Low] The disabled-flag test service could use a compatibilityDate to be more explicit.

This review was generated by an AI assistant and may contain inaccuracies. Please verify all suggestions before applying.

messages = messagesBuilder.finish();

// Extract metadata. If the sender didn't set the field, capnp defaults all values to zero.
auto m = params.getMetadata().getMetrics();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good comment explaining the capnp default-to-zero behavior. This is important for forward/backward compatibility when the sender doesn't populate the metadata field.

fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
connect(address: SocketAddress | string, options?: SocketOptions): Socket;
queue(queueName: string, messages: ServiceBindingQueueMessage[]): Promise<FetcherQueueResult>;
queue(queueName: string, messages: ServiceBindingQueueMessage[], metadata?: MessageBatchMetadata): Promise<FetcherQueueResult>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The metadata?: MessageBatchMetadata parameter in the Fetcher TS override is not gated by the queue_batch_metadata compat flag — it's always visible when service_binding_extra_handlers is on. This means tooling will suggest the parameter even for workers that don't have the metadata flag enabled (the consumer just won't see the data on the batch).

This is reasonable for a testing/service-binding API, but worth confirming this is intentional. Alternatively, you could conditionally include the metadata parameter in the TS override based on the flag, though that adds complexity for arguably little benefit.

Copy link
Author

@KennethRuan KennethRuan Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EDIT: After some more investigation, I would like to keep the metadata?: MessageBatchMetadata parameter on Fetcher ungated.

If we were to add the flag to both the caller side (Fetcher::queue()) and receiver side (queue() handler), I believe it would introduce unnecessary, albeit minor, complexity for rollout and reverts. The Fetcher::queue() method is already behind the experimental service_binding_extra_handlers so we should be safe to make these changes.

That being said, I don't hold a strong opinion on this, so happy to change :)

@ask-bonk
Copy link
Contributor

ask-bonk bot commented Mar 17, 2026

Review posted successfully. Here's a summary of the findings:

Key findings posted on PR #6339:

  1. [Medium] Type choice for metrics fieldsbacklogCount and backlogBytes are conceptually unsigned integers but use double/Float64. This works for JS interop but is worth a design discussion.

  2. [Low] Property accessor patterngetMetadata() returns by value and uses JSG_READONLY_INSTANCE_PROPERTY (eager). This is fine for 3 doubles, just noted the difference from the lazy pattern used by messages.

  3. [Low] Fetcher TS override not flag-gated — The metadata? parameter on Fetcher::queue() is always visible when service_binding_extra_handlers is on, regardless of the queue_batch_metadata flag. Reasonable for a testing API but worth confirming.

  4. [Low] Test module naming — The disabled-test service uses name = "worker-disabled" for the embedded module, which is a bit unusual given it embeds the same file.

  5. [Positive] Capnp default-to-zero comment — Good documentation of the forward-compatibility behavior when metadata is omitted.

  6. [Low] Timestamp unit documentation — Flagged verifying that "ms since epoch" in the capnp comment matches the upstream broker's actual semantics.

No safety, memory, or correctness issues were found. The capnp ordinal (@173) is correct, the compat flag is properly $experimental, both test variants (enabled/disabled) are exercised, and the EW_QUEUE_ISOLATE_TYPES macro correctly includes the new types.

github run

@KennethRuan KennethRuan force-pushed the kruan/MQ-1202-add-metrics-metadata-to-queue-handler branch from 6ea1850 to c232a53 Compare March 18, 2026 07:41
@KennethRuan KennethRuan force-pushed the kruan/MQ-1202-add-metrics-metadata-to-queue-handler branch from c232a53 to 244cd5c Compare March 20, 2026 22:49
@KennethRuan KennethRuan requested a review from a team as a code owner March 20, 2026 22:49
@KennethRuan KennethRuan force-pushed the kruan/MQ-1202-add-metrics-metadata-to-queue-handler branch from 244cd5c to c395270 Compare March 20, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants