Skip to content

v2.17.0

Choose a tag to compare

@bpacholek bpacholek released this 07 Oct 07:22
· 17 commits to main since this release

Minor release. PullConsumerIterator::stop() and drain() called from another fiber now end the pull engine's wait at once (#181). Before, a stop or drain requested while the engine waited on the socket for a pull, or sat out its idle backoff, took effect only when that wait ended: at the earliest pull deadline, up to the pull expiry plus a second, 31 s with the defaults.

Upgrading is recommended if you stop or drain a pull consumer from a signal handler's timer, a supervisor or another fiber. There are no API changes. symfony-nats-messenger 5.4.1 works with this release unchanged.

Fixed

  • stop() and drain() did not end the pull engine's wait (#181). Both set a flag the engine checks at the top of its loop, which it reaches only when its socket read or its idle backoff ends. A stop() from inside the handler was unaffected, since the handler runs just before those checks. Each handle() run now gives the engine a wake-up per flag, which stop() and drain() fire; the engine composes a wake-up into its waits while its flag is still unset, so a latched flag never makes a later wait end early. stop() ends the run at once, and a stop() that lands while a pull of a generation is being written no longer writes the rest of the generation; drain() stops issuing new pulls at once and still lets the in-flight pulls complete, as before. The reviews found that Amp fires a DeferredCancellation as it is destructed, so a second handle() on the same iterator would have fired the previous run's wake-ups: the engine therefore decides by the wake-up itself, not by the flag, and such an orphaned run goes on as before this release instead of spinning. Start the next run only once the previous run's future has resolved; the runs share the stop and drain flags.

Quality gates

  • PHPStan level 8.
  • 2830 unit tests (with data sets) on PHP 8.2 to 8.5, 149 live integration tests and 48 Behat scenarios.
  • All 45 runnable examples executed against a live server.
  • Statement coverage 99.00% from the unit suite (95% floor enforced in CI) and 99.06% combined (97% floor).
  • Infection covered MSI 93.6% over the 3828 mutants it ran (90% floor enforced in CI); it skipped 3972 of the 7800 it generated as too slow, so the score does not include them.
  • Every fix has tests that fail on the old code: the stop was seen only at the pull's deadline, 4 s after it in the tests, or at the end of the idle backoff. On a real nats-server with JetStream, handle() returned 1 ms after a stop() from a timer, where it returned at the server's 10 s pull expiry before.
  • The change was reviewed for semantics and for interleavings by two independent reviewers, and their findings were applied.
  • symfony-nats-messenger 5.4.1's suites pass against this release: PHPStan level max, 528 unit tests, 52 functional scenarios against live NATS and 5 examples.

The full record is in the CHANGELOG.