@@ -93,6 +93,22 @@ class WorkerQueue: public jsg::Object {
9393
9494// Event handler types
9595
96+ // Metadata delivered with a message batch in the queue() handler
97+
98+ struct MessageBatchMetrics {
99+ double backlogCount;
100+ double backlogBytes;
101+ double oldestMessageTimestamp;
102+ JSG_STRUCT (backlogCount, backlogBytes, oldestMessageTimestamp);
103+ JSG_STRUCT_TS_OVERRIDE (MessageBatchMetrics);
104+ };
105+
106+ struct MessageBatchMetadata {
107+ MessageBatchMetrics metrics;
108+ JSG_STRUCT (metrics);
109+ JSG_STRUCT_TS_OVERRIDE (MessageBatchMetadata);
110+ };
111+
96112// Types for other workers passing messages into and responses out of a queue handler.
97113
98114struct IncomingQueueMessage {
@@ -212,6 +228,7 @@ class QueueEvent final: public ExtendableEvent {
212228 struct Params {
213229 kj::String queueName;
214230 kj::Array<IncomingQueueMessage> messages;
231+ MessageBatchMetadata metadata;
215232 };
216233
217234 explicit QueueEvent (jsg::Lock& js,
@@ -227,30 +244,45 @@ class QueueEvent final: public ExtendableEvent {
227244 kj::StringPtr getQueueName () {
228245 return queueName;
229246 }
247+ MessageBatchMetadata getMetadata () {
248+ return metadata;
249+ }
230250
231251 void retryAll (jsg::Optional<QueueRetryOptions> options);
232252 void ackAll ();
233253
234- JSG_RESOURCE_TYPE (QueueEvent) {
254+ JSG_RESOURCE_TYPE (QueueEvent, CompatibilityFlags::Reader flags ) {
235255 JSG_INHERIT (ExtendableEvent);
236256
237257 JSG_LAZY_READONLY_INSTANCE_PROPERTY (messages, getMessages);
238258 JSG_READONLY_INSTANCE_PROPERTY (queue, getQueueName);
239259
260+ if (flags.getWorkerdExperimental ()) {
261+ JSG_READONLY_INSTANCE_PROPERTY (metadata, getMetadata);
262+ }
263+
240264 JSG_METHOD (retryAll);
241265 JSG_METHOD (ackAll);
242266
243267 JSG_TS_ROOT ();
244- JSG_TS_OVERRIDE (QueueEvent<Body = unknown> {
245- readonly messages: readonly Message<Body>[];
246- });
268+ if (flags.getWorkerdExperimental ()) {
269+ JSG_TS_OVERRIDE (QueueEvent<Body = unknown> {
270+ readonly messages: readonly Message<Body>[];
271+ readonly metadata: MessageBatchMetadata;
272+ });
273+ } else {
274+ JSG_TS_OVERRIDE (QueueEvent<Body = unknown> {
275+ readonly messages: readonly Message<Body>[];
276+ });
277+ }
247278 }
248279
249280 void visitForMemoryInfo (jsg::MemoryTracker& tracker) const {
250281 for (auto & message: messages) {
251282 tracker.trackField (" message" , message);
252283 }
253284 tracker.trackField (" queueName" , queueName);
285+ tracker.trackFieldWithSize (" metadata" , sizeof (MessageBatchMetadata));
254286 tracker.trackFieldWithSize (" IoPtr<QueueEventResult>" , sizeof (IoPtr<QueueEventResult>));
255287 }
256288
@@ -274,6 +306,7 @@ class QueueEvent final: public ExtendableEvent {
274306 // array to avoid one intermediate copy?
275307 kj::Array<jsg::Ref<QueueMessage>> messages;
276308 kj::String queueName;
309+ MessageBatchMetadata metadata;
277310 IoPtr<QueueEventResult> result;
278311 CompletionStatus completionStatus = Incomplete{};
279312
@@ -293,24 +326,38 @@ class QueueController final: public jsg::Object {
293326 kj::StringPtr getQueueName () {
294327 return event->getQueueName ();
295328 }
329+ MessageBatchMetadata getMetadata () {
330+ return event->getMetadata ();
331+ }
296332 void retryAll (jsg::Optional<QueueRetryOptions> options) {
297333 event->retryAll (options);
298334 }
299335 void ackAll () {
300336 event->ackAll ();
301337 }
302338
303- JSG_RESOURCE_TYPE (QueueController) {
339+ JSG_RESOURCE_TYPE (QueueController, CompatibilityFlags::Reader flags ) {
304340 JSG_READONLY_INSTANCE_PROPERTY (messages, getMessages);
305341 JSG_READONLY_INSTANCE_PROPERTY (queue, getQueueName);
306342
343+ if (flags.getWorkerdExperimental ()) {
344+ JSG_READONLY_INSTANCE_PROPERTY (metadata, getMetadata);
345+ }
346+
307347 JSG_METHOD (retryAll);
308348 JSG_METHOD (ackAll);
309349
310350 JSG_TS_ROOT ();
311- JSG_TS_OVERRIDE (MessageBatch<Body = unknown> {
312- readonly messages: readonly Message<Body>[];
313- });
351+ if (flags.getWorkerdExperimental ()) {
352+ JSG_TS_OVERRIDE (MessageBatch<Body = unknown> {
353+ readonly messages: readonly Message<Body>[];
354+ readonly metadata: MessageBatchMetadata;
355+ });
356+ } else {
357+ JSG_TS_OVERRIDE (MessageBatch<Body = unknown> {
358+ readonly messages: readonly Message<Body>[];
359+ });
360+ }
314361 }
315362
316363 void visitForMemoryInfo (jsg::MemoryTracker& tracker) const {
@@ -377,8 +424,9 @@ class QueueCustomEvent final: public WorkerInterface::CustomEvent, public kj::Re
377424
378425#define EW_QUEUE_ISOLATE_TYPES \
379426 api::WorkerQueue, api::WorkerQueue::SendOptions, api::WorkerQueue::SendBatchOptions, \
380- api::WorkerQueue::MessageSendRequest, api::IncomingQueueMessage, api::QueueRetryBatch, \
381- api::QueueRetryMessage, api::QueueResponse, api::QueueRetryOptions, api::QueueMessage, \
382- api::QueueEvent, api::QueueController, api::QueueExportedHandler
427+ api::WorkerQueue::MessageSendRequest, api::MessageBatchMetrics, api::MessageBatchMetadata, \
428+ api::IncomingQueueMessage, api::QueueRetryBatch, api::QueueRetryMessage, api::QueueResponse, \
429+ api::QueueRetryOptions, api::QueueMessage, api::QueueEvent, api::QueueController, \
430+ api::QueueExportedHandler
383431
384432} // namespace workerd::api
0 commit comments