v2.7.0
Features
- Pull consumer pipelining (#120). Pull consumers now keep several pull requests in flight over one long-lived pull inbox (
setDepth(), default 2), issuing the next as soon as one retires — eliminating the per-batch round-trip stall and the SUB/UNSUB churn per pull. Throughput rises from ~1 batch per RTT to overlapping pulls (a large gain on higher-latency links). Reply routing matches how a JetStream server actually delivers: status replies route by a per-pull token, while delivered messages (sent on their original subject) are matched to the oldest in-flight pull; the shared pull inbox is slow-consumer exempt so a slow handler never loses a buffered message. - Default pull batch size is now 100 (was 1), with a new
setDepth()controlling overlap.setBatching(1)still works and still pipelines. A consumer that relied on the old batch=1 default now fetches up to 100 messages per pull — size it against yourMaxAckPending/ack_wait, or callsetBatching(1)to restore one-message pulls.
All existing pull-consumer semantics are preserved: stop()/drain(), the escalating idle backoff, finite setIterations(), pinned priority groups (setGroup()) + 423 stale-pin re-pull, terminal-status onError, and reconnect survival. fetchBatch()/fetchNext() are unchanged.
Internal
- Consolidated duplicated boilerplate across the connection, JetStream, and transport layers into shared helpers/traits (#111) — ObjectStore digest/meta-record builders, the JetStream offset-pagination loop, the connect-handshake poll loop, the API-error decode, the Direct Get meta decode (unifying guards that had drifted), and the client TLS-context assembly. No public API or wire-format change.
Full CI green including live-server E2E, integration/behat, and mutation testing (covered MSI ≥ 90%).