Skip to content

Releases: janbalangue/async-bulkhead-ts

v0.4.1

15 Apr 23:31

Choose a tag to compare

[0.4.1] - 2026-04-15

Documentation

  • Corrected the BulkheadOptions API docs in the README to include:
    • name?: string
    • hooks?: BulkheadHooks
  • Clarified hook timing semantics in the README.
  • Documented onRelease as a post-release/post-pump snapshot: if a queued waiter is admitted immediately, the hook may observe inFlight already refilled and pending already reduced.

Notes

  • No runtime behavior changes.
  • No public API changes.
  • This release aligns README documentation with the published 0.4.0 implementation.

v0.4.0

15 Apr 23:18

Choose a tag to compare

[0.4.0] - 2026-04-15

Added

  • Optional name field on BulkheadOptions for bulkhead identification in logs and metrics.
  • Optional synchronous instrumentation hooks on BulkheadOptions:
    • onAcquireSuccess
    • onReject
    • onRelease
    • onClose
  • Operational counters on stats():
    • totalAdmitted
    • totalReleased
    • rejectedByReason
    • hookErrors

Changed

  • stats() now serves as an operational telemetry surface in addition to debug observation.
  • Hook exceptions are swallowed and counted in hookErrors so instrumentation cannot corrupt bulkhead state.
  • Removed an unused internal deque field.

Documentation

  • Added instrumentation examples and hook semantics to the README.
  • Clarified that hooks are synchronous, best-effort, and should remain fast/non-blocking.

Tests

  • Added coverage for hook firing order and state snapshots.
  • Added coverage for totalAdmitted, totalReleased, and rejectedByReason.
  • Added coverage proving hook exceptions do not corrupt state and are counted in hookErrors.

Notes

  • No change to core admission semantics.
  • tryAcquire() remains non-blocking.
  • acquire() remains bounded-wait or fail-fast depending on maxQueue.
  • close() / drain() semantics are unchanged.

v0.3.0

26 Feb 22:17

Choose a tag to compare

v0.3.0 — Graceful Shutdown

Two new APIs for clean process lifecycle management:

  • close() — stops admission permanently, rejects all pending waiters with 'shutdown', rejects all future calls. In-flight work is not interrupted.
  • drain() — returns a promise that resolves when inFlight reaches zero. Works with or without close().
// SIGTERM handler
bulkhead.close();
await bulkhead.drain();
process.exit(0);

Also in this release

  • stats() is now a pure read — no longer mutates the internal queue on every call. Pending count is tracked via an internal counter instead of pruning on read. Safe to poll at high frequency for metrics export.
  • 'shutdown' reject reason added to RejectReason union. Existing consumers are unaffected unless close() is called.
  • closed on stats() — reports whether close() has been called.
  • inFlightUnderflow on stats() — observable invariant counter (should always be 0). Replaces a silent clamp that previously hid potential bugs.
  • New test coverage: mass-abort (100 simultaneous), soak with mid-run shutdown, stats purity, close/drain composition in both orderings.

Upgrading

Fully backward compatible. No breaking changes. The new 'shutdown' reason is additive — code that doesn't call close() will never see it.

If you match on RejectReason exhaustively (e.g. in a switch statement), add a case for 'shutdown'.

Full changelog

See CHANGELOG.md for details.

v0.2.3

22 Feb 18:54

Choose a tag to compare

async-bulkhead-ts v0.2.3

Release date: 2026-02-22
Type: Patch (security-only)

🔐 Security

This release addresses two transitive dependency vulnerabilities:

  • minimatch — enforced to ^10.2.1 (lockfile resolves 10.2.2).
  • ajv — enforced to ^6.12.6 scoped to @eslint/eslintrc to keep ESLint compatible (lockfile resolves 6.12.6).

Secure versions are enforced via npm overrides, ensuring patched resolution even when pulled transitively by dev tooling.

🛠 What Changed

  • Added explicit overrides in package.json to enforce secure dependency resolution.
  • No runtime dependency changes.
  • No public API changes.
  • No behavioral changes.

✅ Compatibility

  • Fully backward compatible.
  • No impact to bulkhead semantics (maxConcurrent, maxQueue, cancellation, FIFO behavior).
  • Safe to upgrade from 0.2.2.

v0.2.2

20 Feb 19:23

Choose a tag to compare

v0.2.2

Internal Queue Hardening

This release strengthens the internal admission queue without changing the public API or external behavior.

Changed

  • Replaced the internal pending queue with a ring-buffer deque to eliminate O(n) operations under contention.
  • Cancelled and timed-out waiters are now pruned deterministically from the front of the queue.
  • Admission drain logic hardened to skip cancelled waiters without head-of-line blocking.

Tests

  • Expanded race coverage for abort/timeout vs. release ordering.
  • Added stress and soak tests to validate maxConcurrent and maxQueue invariants under churn.

Behavioral Notes

  • No public API changes
  • FIFO ordering remains guaranteed when maxQueue is enabled
  • Fail-fast admission remains the default (maxQueue: 0)
  • No semantic changes to tryAcquire(), acquire(), or run()

Why This Matters

Under high cancellation or timeout churn, previous queue implementations could:

  • Perform unnecessary linear operations
  • Temporarily block admission at the head of the queue
  • Risk subtle queue-slot retention under pathological races

v0.2.2 removes those edge-case risks and improves deterministic behavior under contention.

Upgrade Notes

  • No migration required.
  • Safe patch-level upgrade from 0.2.1.

v0.2.0

27 Jan 09:05

Choose a tag to compare

v0.2.0

This release solidifies async-bulkhead-ts as a small, opinionated building block for fail-fast admission control in Node.js services.

What’s new

  • Bounded queue support (opt-in)
    Add maxQueue to allow limited buffering without sacrificing backpressure.
    When both concurrency and queue limits are exceeded, admission fails immediately.

  • Explicit rejection reasons
    Failed admissions now return a structured reason:

    • concurrency_limit
    • queue_limit
  • Improved runtime stats
    Introspection via stats() exposes:

    • inFlight
    • queued
    • configured limits
  • Production-ready packaging

    • Dual ESM + CommonJS builds
    • Full TypeScript typings
    • Tree-shakable (sideEffects: false)
    • Node.js 20+ support

Design principles (unchanged, reinforced)

  • Fail fast by default — no hidden queues
  • No retries, workers, schedulers, or background magic
  • Explicit admit() / release() lifecycle
  • Meant to be composed around, not extended inside

Breaking changes

None.

Notes

Failing to call release() after a successful admission will permanently reduce capacity.
This is an intentional design choice to keep failure modes explicit and observable.

v0.1.0

23 Jan 18:27

Choose a tag to compare

v0.1.0

Initial public release of async-bulkhead-ts.

Added

  • Fail-fast admission control for async workloads
  • Bulkhead concurrency limits with an optional bounded queue
  • Explicit admit() / release() lifecycle
  • Accurate runtime stats (inFlight, queued, limits)
  • ESM and CommonJS builds
  • Full TypeScript typings
  • Stress and soak tests validating concurrency invariants

Design Notes

  • No hidden queues by default
  • No retries, background workers, or scheduling
  • Intended to be composed with higher-level systems, not replace them