You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add bounded typed RequestBatcher with one outcome per accepted request #71
Give independent callers a plain request/result API while combining compatible calls to a bulk endpoint. ShitQuant's multi-token outcome sampling is the reference workload; the API remains domain-neutral.
Replanned on 2026-09-06 against GoBatch master 63ef757 and ShitQuant's recorder, enrichment, paper/replay, and flow workloads. This is an implementation target, not a claim that the behavior already exists.
Required behavior
Use separate request and response types and a unique internal identity for every accepted submission. Repeated lookup keys remain distinct operations unless explicit later coalescing permits equivalence.
Bound accepted/queued requests, active handler calls, batch size and waiting resources; reject or cancel admission explicitly under saturation. Do not spawn one goroutine per internally queued request.
Use max batch size and max linger; do not inherit MinItems/MinTime configurations that can leave a single caller waiting indefinitely. Queue time counts against the caller deadline.
Validate correlation before delivery, including unordered, missing, extra and duplicate responses and partial failure. Never turn a missing result into zero-value success. Adapter-side grouping may map multiple pool rows to one token result.
Distinguish batch transport/protocol failure from per-request failure, preserving trustworthy successes only when attribution is safe.
A caller's cancellation ends its own wait and cannot cancel unrelated callers in the same handler invocation. Handler execution has a lifecycle context and finite timeout.
Make Submit/Close and completion/cancellation races safe; every accepted request gets one terminal outcome. Use a finite graceful-shutdown budget; on expiry terminally settle unresolved waiters with shutdown errors and request execution cancellation. Report actual handler termination separately; do not release active-handler capacity or claim handlers finished until they return.
Provide documented construction, close/abort and error contracts without inheriting stream filtering, stage continuation, or the historical Reader/Writer prototype's channel-close races.
Verification and completion
Use a fixture-backed multi-token market adapter and a generic bulk lookup example. Prove result identity under cancellation and malformed/partial responses, bounded saturation, a lone request, concurrent close, and no lost/duplicate replies. Compare upstream calls and latency with straightforward bounded calls/direct grouping.
Follow the repository's formatting, race-test, vet/lint, package documentation, example and changelog requirements for the changed surface. Report the actual supported behavior and migration; do not treat a passing coverage percentage as proof of these outcomes.
Scope and relationships
Independent of flow and of stream filtering/error-channel redesign. Reuse admission/lifecycle primitives only where their contracts fit; settle the relevant #73/lifecycle decisions within this work if not reused. No generic retries, coalescing, Redis integration or provider credentials in this first API. A published version and clean consumer pin remain separate adoption evidence.
Design history
The earlier report/prototype remains below for provenance; the requirements above supersede conflicting prescriptions. Existing discussion is preserved.
Original issue: Synchronous (blocking) batch Reader/Writer API
Summary
Add a sync subpackage providing synchronous, blocking batch APIs on top of the async batch engine, so callers get the efficiency of batching with a simple call-and-wait interface.
Motivation
The core engine is asynchronous (channels in, errors out). Many real workloads — caching layers, DB access, bulk-capable external APIs — want a plain blocking call (value, err := r.Get(ctx, key)) while still coalescing requests into batches behind the scenes.
Proposed API
From feature/sync-package @ 0fd80a9 (~1,180 LOC, generic BatchReader/BatchWriter):
The prototype handled: per-request context cancellation, request queuing/batching, error propagation (both batch-level and per-item), and graceful shutdown.
Design notes
Should be fully generic over key/value types (the prototype predates the feat: migrate GoBatch API to generics #60 generics migration and needs to align with Batch[T]).
Natural foundation for concrete adapters — see the Redis source/sink adapter issue.
Source (for recovery — branch is being deleted)
feature/sync-package @ 0fd80a9 — files: sync/doc.go, sync/types.go, sync/reader.go, sync/writer.go, plus tests and sync/example_test.go.
changed the title [-]Synchronous (blocking) batch Reader/Writer API[/-][+]Add bounded typed RequestBatcher with one outcome per accepted request[/+]on Sep 6, 2026
Current outcome
Give independent callers a plain request/result API while combining compatible calls to a bulk endpoint. ShitQuant's multi-token outcome sampling is the reference workload; the API remains domain-neutral.
Replanned on 2026-09-06 against GoBatch master
63ef757and ShitQuant's recorder, enrichment, paper/replay, and flow workloads. This is an implementation target, not a claim that the behavior already exists.Required behavior
Verification and completion
Use a fixture-backed multi-token market adapter and a generic bulk lookup example. Prove result identity under cancellation and malformed/partial responses, bounded saturation, a lone request, concurrent close, and no lost/duplicate replies. Compare upstream calls and latency with straightforward bounded calls/direct grouping.
Follow the repository's formatting, race-test, vet/lint, package documentation, example and changelog requirements for the changed surface. Report the actual supported behavior and migration; do not treat a passing coverage percentage as proof of these outcomes.
Scope and relationships
Independent of flow and of stream filtering/error-channel redesign. Reuse admission/lifecycle primitives only where their contracts fit; settle the relevant #73/lifecycle decisions within this work if not reused. No generic retries, coalescing, Redis integration or provider credentials in this first API. A published version and clean consumer pin remain separate adoption evidence.
Design history
The earlier report/prototype remains below for provenance; the requirements above supersede conflicting prescriptions. Existing discussion is preserved.
Original issue: Synchronous (blocking) batch Reader/Writer API
Summary
Add a
syncsubpackage providing synchronous, blocking batch APIs on top of the async batch engine, so callers get the efficiency of batching with a simple call-and-wait interface.Motivation
The core engine is asynchronous (channels in, errors out). Many real workloads — caching layers, DB access, bulk-capable external APIs — want a plain blocking call (
value, err := r.Get(ctx, key)) while still coalescing requests into batches behind the scenes.Proposed API
From
feature/sync-package@0fd80a9(~1,180 LOC, genericBatchReader/BatchWriter):The prototype handled: per-request
contextcancellation, request queuing/batching, error propagation (both batch-level and per-item), and graceful shutdown.Design notes
Batch[T]).Source (for recovery — branch is being deleted)
feature/sync-package@0fd80a9— files:sync/doc.go,sync/types.go,sync/reader.go,sync/writer.go, plus tests andsync/example_test.go.Related: #72 (Redis adapter builds on this API)