feat(node): producer-side batch accumulator - #544
Conversation
Buffers enqueues for one task and flushes them through enqueueMany on a size or time trigger, matching Java's Batcher and Python's BatchAccumulator.
Also documents enqueueMany, which Node shipped undocumented.
|
Warning Review limit reached
Next review available in: 47 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds a Node.js ChangesNode producer batching
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Producer
participant Queue
participant Batcher
participant Storage
Producer->>Queue: batcher(task, options)
Queue->>Batcher: construct batcher
Producer->>Batcher: add(args, options)
Batcher->>Batcher: buffer entries until threshold or timer
Batcher->>Queue: enqueueMany(entries)
Queue->>Storage: persist batch
Storage-->>Queue: return job ids
Queue-->>Batcher: return job ids
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@sdks/node/src/batching.ts`:
- Around line 176-188: Update the error handling in the timer callback around
flush and the onError branch so an exception thrown by onError is caught and
contained, while still ensuring the existing re-arm logic runs for open batches
with buffered entries. Preserve the current warning behavior when no onError
handler is configured.
- Around line 79-82: Update the maxWaitMs validation in the batcher options
initialization to reject values above Node’s maximum supported timer delay,
2_147_483_647 milliseconds, in addition to the existing finite positive check.
Keep arm() passing the validated value to setTimeout and preserve the current
RangeError behavior and message context.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0c75ee3e-3e4f-4b49-9d66-b83159b45cb6
📒 Files selected for processing (13)
CHANGELOG.mddocs/content/docs/node/api-reference/batching.mdxdocs/content/docs/node/api-reference/index.mdxdocs/content/docs/node/api-reference/meta.jsondocs/content/docs/node/guides/core/batching.mdxdocs/content/docs/node/guides/core/index.mdxdocs/content/docs/node/guides/core/meta.jsondocs/content/docs/resources/changelog.mdxdocs/content/docs/shared/guides/core/tasks.mdxsdks/node/src/batching.tssdks/node/src/index.tssdks/node/src/queue.tssdks/node/test/core/batcher.test.ts
Node clamps a setTimeout delay above 2147483647ms to 1ms, turning a long wait into an immediate flush.
A handler that threw escaped the timer callback as an uncaught exception and skipped the re-arm, stranding the buffered entries.
Closes #516.
Node had
enqueueManybut no accumulator that flushes on size or interval — Python hasBatchAccumulator, Java hasBatcher<T>. This addsBatcherplus aqueue.batcher(name, options?)factory.Which shape
Java's, not Python's. Java and Node buffer enqueues and flush N jobs through
enqueueMany; Python coalesces buffered items into one job whose payload is the list, which needs a worker-side batch-handler contract (per-item results, partial-failure retry) that Node doesn't have. The issue framed the gap as an accumulator overenqueueMany. Python's@task(batch=)coalescing stays Python-only and is worth its own issue.One place it goes further than Java:
add(args, options?)keeps per-entryEnqueueOptions, because Node'senqueueManytakes options per entry where Java's takes one shared set.Failure and lifecycle
flush()splices the buffer before callingenqueueMany— ajob.enqueuedhandler runs synchronously inside it and can re-enteradd— and on throw puts the entries back at the head, so submission order holds.onError(or logs) and re-arms; otherwise entries would strand until the nextadd.unref'd like every other timer in the SDK, so a partial buffer never holds the process open — and is lost on a bare exit.close()/usingis the documented shutdown path.RangeError;addafter close throwsQueueError.Docs
New
node/api-reference/batching.mdxandnode/guides/core/batching.mdx. The API page also documentsenqueueMany, which Node had shipped undocumented, and the guide mirrors Java's producer-batching vs dequeue-batchSizeframing. The Node block inshared/guides/core/tasks.mdxpointed only at enqueue-options; it now links the new guide.Testing
12 tests in
test/core/batcher.test.ts: size flush, timed flush, close/idempotence,Symbol.dispose, per-entry options, end-to-end run, failed flush retains entries,onErrorplus timed retry, tunable validation, argument typing, andjob.enqueuedre-entrancy.Full Node suite 511 passed / 88 skipped; the 10
test/dashboard/failures are pre-existing locally (novitein thedashboard/workspace). Typecheck and biome clean; docscheck:parityand docs build clean.Summary by CodeRabbit
New Features
enqueueManyand theBatcherhelper.close()andusing/Symbol.dispose.Documentation