From 409b0287d6dbbbfe79083d37d192d2f876ae5e27 Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 13:00:42 -0500 Subject: [PATCH 01/10] ALLI-21969: clean up grammar and phrasing --- CHANGELOG.md | 78 ++++++++++--------- README.md | 6 +- UPGRADE-3.0.md | 14 ++-- UPGRADE-4.0.md | 12 +-- UPGRADE-5.0.md | 27 +++---- UPGRADE-6.0.md | 6 +- docs/consumers.rst | 72 ++++++++--------- docs/drivers.rst | 37 ++++----- docs/handlers.rst | 28 +++---- docs/index.rst | 20 ++--- docs/messages.rst | 14 ++-- docs/producers.rst | 15 ++-- examples/plain_object_message.php | 6 +- examples/simple.php | 6 +- src/Consumer.php | 8 +- src/Driver.php | 20 ++--- src/Envelope.php | 6 +- src/Exception/SimpleMustStop.php | 2 +- src/Handler/Pcntl/Pcntl.php | 19 ++--- src/Handler/PcntlForkingHandler.php | 14 ++-- src/MessageHandler.php | 9 ++- src/MessageLifecycle.php | 19 ++--- src/RetrySpec.php | 6 +- src/Serializer/NativeSerializer.php | 4 +- src/Signer/Signer.php | 13 ++-- src/Signer/SodiumCryptoAuth.php | 2 +- .../HmacSha256NativeSerializerTest.php | 2 +- test/unit/DefaultEnvelopeTest.php | 2 +- 28 files changed, 238 insertions(+), 229 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3160754..37d453d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,21 +7,21 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed -- `once` calls with no message handled will have an `{queueName} empty-receive` +- `once` calls that handle no message will use an `{queueName} empty-receive` span name. ## 6.1.1 ### Fixed -- Fixed the open telemetry `_register.php` file autoload +- Fixed autoloading for the OpenTelemetry `_register.php` file. ## 6.1.0 ### Added -- Added open telemetry instrumentation around `Consumer::once` and - `Driver::enqueue`. These respect [messaging span](https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/) +- Added OpenTelemetry instrumentation around `Consumer::once` and + `Driver::enqueue`. These follow [messaging span](https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/) semantic conventions. ## 6.0.0 @@ -37,7 +37,7 @@ See [the upgrade guide](UPGRADE-6.0.md) for more information. ### Added -- Support PHP `^7.4 || ^8.0` +- Added support for PHP `^7.4 || ^8.0` ### Changed @@ -49,26 +49,26 @@ See [the upgrade guide](UPGRADE-6.0.md) for more information. - PHP 7.3+ is required. - Implementing `PMG\Queue\Message` is no longer required! Messages passed - to the the producer and handled by the consumer can be any PHP object now. - In the cases where a plain object is used, the message *name* is the full - qualified class name. However, you may implement `Message` should you desire to + to the producer and handled by the consumer can now be any PHP object. + When a plain object is used, the message *name* is the fully qualified + class name. However, you may implement `Message` if you want to keep the old behavior of having a specific message name that differs from the FQCN. - `PMG\Queue\Router::queueFor` now typehints against `object` instead of `Message`. - All `PMG\Queue\MessageLifecycle` methods now typehint against `object`. - `PMG\Queue\Envelope` and `DefaultEnvelope` now deal with `object` messages - only and do not typehint again `Message`. -- `PMG\Queue\Driver::enqueue` now typehints agains `object` instead of message. - if a driver gets an `Envelope` instance it should use that instead of creating + only and no longer typehint against `Message`. +- `PMG\Queue\Driver::enqueue` now typehints against `object` instead of `Message`. + If a driver gets an `Envelope` instance, it should use that instead of creating its own envelope. See [`UPGRADE-5.0.md`](/UPGRADE-5.0.md) for more details. - `PMG\Queue\MessageHandler::handle` now typehints against `object` instead of `Message`. - `PMG\Queue\Producer::send` now typehints against `object` instead of `Message`. -- `MessageLifecycle::failed` no longer has an `$isRetrying` argument, instead - `MessageLifecycyle::retrying` will be called instead. +- `MessageLifecycle::failed` no longer has an `$isRetrying` argument. Instead, + `MessageLifecycle::retrying` will be called. - `PMG\Queue\Router::queueFor` now has a `?string` return type. -- Drivers should no longer call `Envelope::retry` instead, instead consumers +- Drivers should no longer call `Envelope::retry`. Instead, consumers should call this method along with any delay required from the `RetrySpec`. See `UPGRADE-5.0.md` for more details. @@ -78,17 +78,17 @@ n/a ### Added -- A new `MessageLifecycle::retrying` method was added that gets called whenever +- A new `MessageLifecycle::retrying` method was added and is called whenever a message fails and is retrying. - `PMG\Queue\Lifecycle\DelegatingLifecycle` has a new named constructor: `fromIterable`. This uses PHP 7.1's `iterable` pseudo type. -- `RetrySpec::retryDelay` method added to allow a message to be delayed when - retrying, if the driver supports it. +- The `RetrySpec::retryDelay` method was added to allow a message to be delayed + when retrying, if the driver supports it. - `Envelope::retry` now accepts an `int $delay` to support delayed retries. Not all - drivers will be able to support delaying. + drivers will support delays. - Similarly, `PMG\Queue\Driver` implementations must no longer call - `Envelope::retry` as they were required to do previously. See `UPGRADE-5.0.md` - for more details. Instead `PMG\Queue\Consumer` implementations should call + `Envelope::retry`. See `UPGRADE-5.0.md` for more details. Instead, + `PMG\Queue\Consumer` implementations should call `Envelope::retry`. ### Removed @@ -145,13 +145,13 @@ n/a to `ensureSerializer`. - [BC Break, Internals] `Driver` now has more strict type declarations. - [BC Break, Internals] `Driver::release` was introduced. -- [BC Break, Internals] `Consumer::once` and `Consumer::run` Now take an optional - `MessageLifecycle` instance as their second argument. Only folks who wrote +- [BC Break, Internals] `Consumer::once` and `Consumer::run` now take an optional + `MessageLifecycle` instance as their second argument. Only people who wrote custom consumer implementations need to worry about this. See `DefaultConsumer` - for an example how this may be handled. End users can keep using the consumer - exactly as they were. + for an example of how this may be handled. End users can keep using the + consumer as before. - [BC Break, Internals] `MessageHandler::handle` now returns a promise object - from the `guzzlehttp/promises` library. Only folks who wrote custom handler + from the `guzzlehttp/promises` library. Only people who wrote custom handler implementations need to worry about this. - `RetrySpec::canRetry` now has a return type hint. - `Consumer::once` and `Consumer::run` have `string` typehints for their @@ -182,10 +182,10 @@ n/a ### Added -- Child processes that exit abnormaly in `PcntlForkingHandler` now throw an - `AbnormalExit` exception with some info about what went wrong. Practically - this has no impact: the job is still failed and (possibly) retried, but the - thrown exception will be logged and hopefully give users a better place to +- Child processes that exit abnormally in `PcntlForkingHandler` now throw an + `AbnormalExit` exception with some information about what went wrong. + Practically, this has no impact: the job still fails and may be retried, but + the thrown exception will be logged to give users a better place to start debugging. @@ -194,8 +194,8 @@ n/a ### Changed - `PcntlForkingHandler` now throws a `CouldNotFork` exception that causes the - consumer to exit unsuccessfully. Since a failure to fork is clearly on level - with a driver error -- a system issue, not an application issue -- this is + consumer to exit unsuccessfully. Since a failure to fork is on the same level + as a driver error, a system issue rather than an application issue, this is more in line with what *should* happen. The consumer will exit and its process manager can restart it. @@ -205,7 +205,8 @@ n/a ### Added - There is a new `PMG\Queue\Handler\Pcntl` class that acts as a thin wrapper - around the `pcntl_*` functions and `exit`. Mostly done for testing purposes. + around the `pcntl_*` functions and `exit`. This exists mostly for testing + purposes. ## 3.0.0 @@ -214,16 +215,17 @@ n/a - [BC BREAK] PHP version requirement was bumped to 5.6 - [BC BREAK] `DefaultConsumer::once` (and the `Consumer` interface) have been changed to make `once` safe to run in a loop. In other words, it never throws - exceptions unless it's a must stop or an exception thrown from a driver. All - other exceptions are logged, but not fatal. The idea here is to make consumers + exceptions unless it is a must-stop exception or an exception thrown from a + driver. All other exceptions are logged but are not fatal. The idea here is + to make consumers safe to decorate without having to duplicate the error handling logic. - [BC BREAK] `PMG\Queue\Serializer\SigningSerializer` has been merged into `NativeSerializer` and removed. Pass your key as the first argument to `NativeSerializer`'s constructor. - [BC BREAK] `AbstractPersistanceDriver::getSerializer` was removed, use `AbstractPersistanceDriver::assureSerializer` instead. -- [BC BREAK] `Consumer::stop` now takes an optional exit code. Only really - relevant for implementors or the `Consumer` interface. +- [BC BREAK] `Consumer::stop` now takes an optional exit code. This is mainly + relevant for implementers of the `Consumer` interface. - [BC BREAK] `MessageExecutor`, `HandlerResolver`, and their implementations have been removed. See `UPGRADE-3.0.md` for some info on migration. - `Consumer` has docblocks that reflect its actual return values now. @@ -253,7 +255,7 @@ BC Breaks: Bug Fixes: - `SigningSerializer` now uses `hash_equals` instead of strict equality. PHP 5.5 - users will fallback on the Symfony 5.6 polyfill. + users will fall back to the Symfony 5.6 polyfill. New Features: @@ -287,7 +289,7 @@ Bug Fixes: BC Breaks: -- everything, completely refactored +- Everything was refactored. New Features: diff --git a/README.md b/README.md index bff746d..8d787d7 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ # PMG\Queue -`pmg/queue` is a production ready queue framework that powers many internal +`pmg/queue` is a production-ready queue framework that powers many internal projects at [PMG](https://www.pmg.com/). -It's simple and extensible a number of features we've found to be the most -useful including automatic retries and multi-queue support. +It is simple and extensible, with features we have found most useful, +including automatic retries and multi-queue support. ## [Documentation](http://pmg-queue.readthedocs.io/en/latest/) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index a2e1c90..bcfdae8 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -10,16 +10,16 @@ The biggest change is the extraction of the `PheanstalkDriver` into its own library. Rather than `composer require pmg/queue`, you'll want to require the pheanstalk driver instead: `composer require pmg/queue-pheanstalk`. -## Introduction of `MessageHandler` and removal of Exectors & Resolvers +## Introduction of `MessageHandler` and Removal of Executors & Resolvers -Previously you gave the consumer an instance of a `MessageExector` that wrapped +Previously, you gave the consumer an instance of a `MessageExecutor` that wrapped up a `HandlerResolver`. The point of this was to map callables to message names. -In 3.0, we replace those two things with a single `MessageHandler` interface. -There are two built in: a `CallableHandler` and `PcntlForkingHandler`. +In 3.0, those two pieces are replaced by a single `MessageHandler` interface. +There are two built-in options: a `CallableHandler` and `PcntlForkingHandler`. -This was done to better reflect how PMG is using the Queue (and how we think it -should be used). +This change better reflects how PMG uses Queue and how we think it should be +used. ### 2.X @@ -65,7 +65,7 @@ No problem, it was moved into its own library. composer require pmg/queue-mapping-handler ``` -And use it like so: +Use it like this: ```php use PMG\Queue as Q; diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index be1b2bf..a90df98 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -2,12 +2,12 @@ ## PHP Version Requirement Bumped to ~7.0 -Support for PHP 5.6+ dropped. Stick with 3.X need PHP 5 support is still +Support for PHP 5.6+ was dropped. Stick with 3.X if PHP 5 support is still necessary. ## `NativeSerializer` Now Requires a `Signer` Instance -Previously one could pass a key to `NativeSerializer` directly. Now a `Signer` +Previously, you could pass a key to `NativeSerializer` directly. Now a `Signer` instance is required. A named constructor is provided if the 3.X behavior is still desired. @@ -33,9 +33,9 @@ for more info. ## For Handler Authors -Implementation of `MessageHandler` now requires a `GuzzleHttp\Promise\PromiseInterface` -be returned from the `handle` method. This lets consumers do much more graceful -stopping. If your handler does not *really* need a promise, use `FulfilledPromise`: +Implementing `MessageHandler` now requires returning a `GuzzleHttp\Promise\PromiseInterface` +from the `handle` method. This lets consumers stop much more gracefully. +If your handler does not *really* need a promise, use `FulfilledPromise`: ```php use GuzzleHttp\Promise\FulfilledPromise; @@ -62,7 +62,7 @@ for the updated method signatures. ### `Driver::release` was Added -This is a method that should skip the retry system for the given +This method should skip the retry system for the given envelope/message and put it back into a ready state immediately. ### `assureSerializer` was renamed in `AbstractPersistanceDriver` diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 1e0fc21..2af1493 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -2,22 +2,23 @@ ## PHP Version Requirement Bumped to ~7.3 -Stick with version 4.X should PHP 7.0, 7.1, or 7.2 support be required. +Stick with version 4.X if PHP 7.0, 7.1, or 7.2 support is required. ## Messages No Longer Need to Implement `PMG\Queue\Message` -Producers and consumers can now deal with plain objects. By default the *message name* -for plain object messgaes is the fully qualified class name (FQCN). +Producers and consumers can now deal with plain objects. By default, the +*message name* for plain object messages is the fully qualified class name +(FQCN). You may, however, implement `PMG\Queue\Message` (and its `getName` method) should you want to continue using message names other than FQCNs. -The `PMG\Queue\MessageTrait` which provided the FQCN as a name behavior was also +The `PMG\Queue\MessageTrait`, which provided FQCN-based naming, was also removed. ### Router Updates for Message Names -The producers routing configuration may need to be updated should you choose to +The producer's routing configuration may need to be updated should you choose to use FQCNs as the message names. #### Version 4.X @@ -43,8 +44,8 @@ $router = new MappingRouter([ ## `MessageLifecycle` Has a New `retrying` Method -Rather than have an `$isRetrying` flag in the `failed` method. If the message is -being retried the `retrying` method will be invoked, otherwise `failed` will. +Instead of using an `$isRetrying` flag in the `failed` method, the consumer now +calls `retrying` when a message is being retried and `failed` otherwise. This should be a pretty easy upgrade: @@ -127,9 +128,9 @@ final class CustomRouter implements Router } ``` -## `MessageHandler::handle` Now Accept an Object +## `MessageHandler::handle` Now Accepts an Object -Any custom implementation of `MessageHandler` will need to be udpated. +Any custom implementation of `MessageHandler` will need to be updated. ```diff use GuzzleHttp\Promise\PromiseInterface; @@ -156,8 +157,8 @@ All changes here are only relevant to authors of `PMG\Queue\Driver`, And `send` now has a `void` return type as well. -This is part of a broader change (see above) around pmg/queue dealing with -plain `object` without the requirement of a `Message` implementation. +This is part of a broader change (see above) around `pmg/queue` handling plain +objects without requiring a `Message` implementation. ```diff -use PMG\Queue\Message; @@ -177,7 +178,7 @@ plain `object` without the requirement of a `Message` implementation. ### `Driver::enqueue` Now Takes an `object` Instead of a `Message` Drivers should handle receiving an `Envelope` instance in this method as well. -Should that happen the driver *must* use that envelope instead of creating its +If that happens, the driver *must* use that envelope instead of creating its own. @@ -209,7 +210,7 @@ own. In 4.X (and lower) drivers were required to call `$envelope->retry()` on any envelope passed in `Driver::retry`. -That should now happen in implements of `PMG\Queue\Consumer` instead. +That should now happen in implementations of `PMG\Queue\Consumer` instead. #### Version 4.X Driver diff --git a/UPGRADE-6.0.md b/UPGRADE-6.0.md index 3f9d439..0b8da13 100644 --- a/UPGRADE-6.0.md +++ b/UPGRADE-6.0.md @@ -2,7 +2,7 @@ ## PHP Version Requirement Bumped to ^8.0 -Stick with version 5.X should PHP ^7.3 support be required. +Stick with version 5.X if PHP ^7.3 support is required. ## Lifecycle Changes @@ -17,5 +17,5 @@ Stick with version 5.X should PHP ^7.3 support be required. ## MessageTrait -- `PMG\Queue\MessageTrait` was removed, the default behavior has been to use the - FQCN since 5.X, so this added no additional functionalty. +- `PMG\Queue\MessageTrait` was removed. The default behavior has been to use the + FQCN since 5.X, so this added no additional functionality. diff --git a/docs/consumers.rst b/docs/consumers.rst index 1fc8546..0a9ec24 100644 --- a/docs/consumers.rst +++ b/docs/consumers.rst @@ -1,12 +1,12 @@ Consumers ========= -Implementations of ``PMG\Queue\Consumer`` pull message out of a driver backend -and handle (process) them in some way. The default consumer accomplishes this a -:doc:`message handler `. +Implementations of ``PMG\Queue\Consumer`` pull messages out of a driver backend +and handle (process) them in some way. The default consumer accomplishes this +through a :doc:`message handler `. -In all cases ``$queueName`` in the consume should correspond to queues into -which your :doc:`producer ` put messages. +In all cases, ``$queueName`` in the consumer should correspond to queues into +which your :doc:`producer ` puts messages. .. php:interface:: Consumer @@ -18,30 +18,30 @@ which your :doc:`producer ` put messages. :param string $queueName: The queue from which the messages will be processed. :param MessageLifecycle|null $lifecycle: An optional message lifecycle. - :throws: ``PMG\Queue\Exception\DriverError`` If some things goes wrong + :throws: ``PMG\Queue\Exception\DriverError`` If something goes wrong with the underlying driver. Generally this happens if the persistent - backend goes down or is unreachable. Without the driver the consumer + backend goes down or is unreachable. Without the driver, the consumer can't do its work. :returns: An exit code :rtype: int .. php:method:: once($queueName, MessageLifecycle $lifecycle=null) - Consume and handle a single message from $queueName + Consume and handle a single message from $queueName. :param string $queueName: The queue from which the messages will be processed. :param MessageLifecycle|null $lifecycle: An optional message lifecycle. - :throws: PMG\\Queue\\Exception\\DriverError If some things goes wrong + :throws: PMG\\Queue\\Exception\\DriverError If something goes wrong with the underlying driver. Generally this happens if the persistent - backend goes down or is unreachable. Without the driver the consumer + backend goes down or is unreachable. Without the driver, the consumer can't do its work. - :returns: True or false to indicate if the message was handled successfully. - null if no message was handled. + :returns: True or false to indicate whether the message was handled successfully. + Null if no message was handled. :rtype: boolean or null .. php:method:: stop(int $code) - Used on a running consumer this will tell it to gracefully stop on its + Calling this on a running consumer tells it to stop gracefully on its next iteration. :param int $code: The exit code to return from `run` @@ -70,12 +70,13 @@ The script to run your consumer might look something like this. Check out the Retrying Messages ----------------- -When a message fails -- by throwing an exception or returns false from a -``MessageHandler`` -- the consumer puts it back in the queue to retry up to 5 -times by default. This behavior can be adjusted by providing a ``RetrySpec`` as -the third argument to the ``DefaultConsumer`` constructor. `pmg/queue` provides a -few by default. Additionally, ``RetrySpec`` provides a method for calculating -how long a message should be delayed before it can be retried. +When a message fails, either by throwing an exception or by returning ``false`` +from a ``MessageHandler``, the consumer puts it back in the queue and retries +it up to five times by default. This behavior can be adjusted by providing a +``RetrySpec`` as the third argument to the ``DefaultConsumer`` constructor. +``pmg/queue`` provides a few retry specs by default. Additionally, +``RetrySpec`` provides a method for calculating how long a message should be +delayed before it can be retried. Not all :ref:`drivers ` support retry delays. Check the driver's documentation for more details. @@ -90,20 +91,20 @@ Retry specs look at ``PMG\Queue\Envelope`` instances, not raw messages. See the .. php:method:: canRetry(PMG\\Queue\\Envelope $env) - Inspects an envelop to see if it can retry again. + Inspects an envelope to see whether it can be retried again. :param $env: The message envelope to check :returns: true if the message can be retried, false otherwise. :rtype: boolean - .. php:method: retryDelay(PMG\\Queue\Envelope $env) + .. php:method:: retryDelay(PMG\\Queue\\Envelope $env) - Determines how long the message should be delays before retrying again. + Determines how long the message should be delayed before retrying again. Not all queue drivers will support retry delays. :param $env: The message envelope for which the delay should be calculated :returns: The delay in seconds - :rtype: boolean + :rtype: int Limited Retries @@ -173,9 +174,9 @@ argument to ``DefaultConsumer``'s constructor. Using Message Lifecycles ------------------------ -A ``MessageLifecycle`` implementation provides a look into a message as it -moves through the consumer. The goal is to allow an application to hook into a -consumer processing to take actions they want. Say an application requires +A ``MessageLifecycle`` implementation provides visibility into a message as it +moves through the consumer. The goal is to allow an application to hook into +consumer processing and take the actions it needs. Say an application requires sending a notification when a message fails and will not be retried. .. code-block:: php @@ -221,16 +222,16 @@ same time as the queue name, it's up to the implementation to decide if they care about that detail. If the implementation does care, it can take the queue name as a constructor argument. -We've found at PMG that most times queue name is a detail that simply does not -matter to the application itself. It's just a way to distribute work. +We've found at PMG that, most of the time, the queue name is a detail that does +not matter to the application itself. It's just a way to distribute work. Provided Message Lifecycles """"""""""""""""""""""""""" -A ``NullLifecycle``, mentioned above, that does nothing. This makes a convenient +A ``NullLifecycle``, mentioned above, does nothing. This makes a convenient base class to extend and implement what methods your application requires. -Additionally there are a few other provided ``MessageLifecycle`` implementations. +There are a few other provided ``MessageLifecycle`` implementations. ``DelegatingLifecycle`` proxies to multiple child lifecycles. Use this to compose other lifecycles together. In the example below, both ``NotifyingLifecycle`` and @@ -258,7 +259,7 @@ moves. name. Use this if specific ``MessageLifecycle`` implementations need to fire for specific messages. In the example below ``NotifyingLifecycle`` would track ``messageA`` through its lifecycle and ``SomeOtherLifecycle`` would track -``messageB``. Any other message would fallback to ``FallbackLifecycle``. +``messageB``. Any other message would fall back to ``FallbackLifecycle``. .. code-block:: php @@ -279,7 +280,7 @@ for specific messages. In the example below ``NotifyingLifecycle`` would track 'messageB' => new SomeOtherLifecycle(), ]); -These two implementations could be combined as well. +You can combine these two implementations as well. .. code-block:: php @@ -301,7 +302,7 @@ These two implementations could be combined as well. Build Custom Consumers ---------------------- -Extend ``PMG\\Queue\\AbstractConsumer`` to make things easy and +Extend ``PMG\\Queue\\AbstractConsumer`` to make implementation easier and implement the ``once`` method. Here's an example that decorates another ``Consumer`` with events. @@ -322,12 +323,13 @@ implement the ``once`` method. Here's an example that decorates another /** @var EventDispatcherInterface $events */ - // constructor that takes a consumer and dispatcher to set the props ^ + // constructor omitted; it should accept a consumer and dispatcher and + // assign the properties above. public function once($queueName) { $this->events->dispatch('queue:before_once', new Event()); $this->wrapped->once($queueName); - $this->events->disaptch('queue:after_once', new Event()); + $this->events->dispatch('queue:after_once', new Event()); } } diff --git a/docs/drivers.rst b/docs/drivers.rst index 4228259..cbb9eec 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -10,11 +10,11 @@ Drivers ------- Drivers are the queue backend hidden behind the ``PMG\Queue\Driver`` interface. -``pmg/queue`` comes with two drivers built in: *memory* and *pheanstalk* +``pmg/queue`` comes with two built-in drivers: *memory* and *pheanstalk* (beanstalkd). -Drivers have method for enqueuing and dequeueing messages as well as methods for -acknowledging a message is complete, retrying a message, or marking a message +Drivers have methods for enqueuing and dequeueing messages as well as methods +for acknowledging that a message is complete, retrying a message, or marking a message as failed. .. _envelopes: @@ -25,7 +25,7 @@ Envelopes Envelopes wrap up :doc:`messages ` to allow drivers to add additional metadata. One example of such metadata is a :ref:`retry count ` that the :doc:`consumers ` may use to determine if a message should be -retried. The :ref:`pheanstalk driver ` implements its own envelop +retried. The :ref:`pheanstalk driver ` implements its own envelope class so it can track the beanstalkd job identifier for the message. Drivers are free to do whatever they need to do as long as their envelope @@ -34,7 +34,7 @@ implements ``PMG\Queue\Envelope``. Driver Implementations ---------------------- -The core ``pmg/queue`` library provides a in memory driver and PMG maintains a +The core ``pmg/queue`` library provides an in-memory driver, and PMG maintains a `driver for beanstalkd `_ that uses the `pheanstalk `_ library. @@ -61,9 +61,9 @@ keeps messages in memory. // $handler instanceof PMG\Queue\MessageHandler $consumer = new DefaultConsumer($driver, $handler); -The memory driver is not very useful outside of testing. For instance, -while doing end to end tests, you may want to switch out your producers library -to use the memory driver then verify the expected messages when into it. +The memory driver is not especially useful outside of testing. For instance, +while doing end-to-end tests, you may want your producer layer to use the +memory driver and then verify that the expected messages went into it. .. code-block:: php @@ -79,7 +79,8 @@ to use the memory driver then verify the expected messages when into it. public function testSomething() { - // imagine some stuff happened before this, now we need to verify that + // imagine some setup happened before this; now we need to verify + // that the expected message is in the queue. $envelope = $this->driver->dequeue(self::TESTQ); @@ -131,13 +132,13 @@ and :doc:`messages ` to something the persistent backend can store. Similarly, whatever is stored in the queue backend needs to be turned back into a message. **Serializers** make that happen. -All serializers implements ``PMG\Queue\Serializer\Serializer`` and one -implementation is provied by default: ``NativeSerializer``. +All serializers implement ``PMG\Queue\Serializer\Serializer``, and one +implementation is provided by default: ``NativeSerializer``. -``NativeSerializer`` uses PHP's build in ``serialize`` and ``unserialize`` +``NativeSerializer`` uses PHP's built-in ``serialize`` and ``unserialize`` functions. Serialized envelopes are base64 encoded and signed (via a ``Signer``). -The signature is a way to authenticate the message: make sure it came from a -known source and hasn't been tampered with +The signature authenticates the message and helps ensure it came from a known +source and has not been tampered with. .. code-block:: php @@ -151,8 +152,8 @@ known source and hasn't been tampered with // ... -Should want to use ``ext-libsodium`` or the built in libsodium support in PHP -7.2+ there is also a ``SodiumCryptoAuth`` signer. +If you want to use ``ext-libsodium`` or the built-in libsodium support in PHP +7.2+, there is also a ``SodiumCryptoAuth`` signer. .. code-block:: php @@ -196,5 +197,5 @@ Implementing Your Own Drivers ----------------------------- Persistent drivers are not required to use serializers (or anything else), but -if they do ``PMG\Queue\Driver\AbstractPersistanceDriver`` provides helpers for -the usage of serializers. +if they do, ``PMG\Queue\Driver\AbstractPersistanceDriver`` provides helpers for +using serializers. diff --git a/docs/handlers.rst b/docs/handlers.rst index 2f63962..bd5aa58 100644 --- a/docs/handlers.rst +++ b/docs/handlers.rst @@ -3,7 +3,7 @@ Message Handlers A message handler is used by ``DefaultConsumer`` to do the actual work of processing a message. Handlers implement ``PMG\Queue\MessageHandler`` which -accepts a message and a set of options from the the consumer as its arguments. +accepts a message and a set of options from the consumer as its arguments. Every single message goes through a single handler. It's up to that handler to figure out how to deal with each message appropriately. @@ -18,7 +18,7 @@ figure out how to deal with each message appropriately. :param $handle: The message to handle. :param $options: A set of options from the consumer. - :return: A boolean indicated whether the message was handled successfully. + :return: A boolean indicating whether the message was handled successfully. :rtype: boolean @@ -53,7 +53,7 @@ with the message. Multiple Handlers with Mapping Handler -------------------------------------- -The above `switch` statement is a lot of boilerplaint, so PMG provies a +The above `switch` statement is a lot of boilerplate, so PMG provides a `mapping handler `_ that looks up callables for a message based on its name. For example, here's a callable for the :ref:`send alert message `. @@ -87,7 +87,7 @@ here's a callable for the :ref:`send alert message `. } } -Now pull in the mapping handler with ``composer require pmg/queue-mapping-handler`` +Now pull in the mapping handler with ``composer require pmg/queue-mapping-handler`` and we can integrate the callable above with it. .. code-block:: php @@ -110,11 +110,11 @@ Using Tactician to Handle Messages ---------------------------------- `Tactician `_ is a command bus from The PHP -League. You can use it to do message handling with the queue. +League. You can use it to handle messages with the queue. .. code-block:: bash - composer install pmg/queue-tactician + composer require pmg/queue-tactician Use the same command bus with each message. @@ -124,14 +124,14 @@ Use the same command bus with each message. use League\Tactician\CommandBus; use PMG\Queue\DefaultConsumer; - use PMG\Queue\Handler\TaticianHandler; + use PMG\Queue\Handler\TacticianHandler; $handler = new TacticianHandler(new CommandBus(/* ... */)); /** @var PMG\Queue\Driver $driver */ $consumer = new DefaultConsumer($driver, $handler); -Alternative, you can create a new command bus to handle each message with +Alternatively, you can create a new command bus to handle each message with `CreatingTacticianHandler`. This is useful if you're using :ref:`forking child processes ` to handle messages. @@ -141,9 +141,9 @@ Alternative, you can create a new command bus to handle each message with use League\Tactician\CommandBus; use PMG\Queue\DefaultConsumer; - use PMG\Queue\Handler\CreatingTaticianHandler; + use PMG\Queue\Handler\CreatingTacticianHandler; - $handler = new TacticianHandler(function () { + $handler = new CreatingTacticianHandler(function () { return new CommandBus(/* ... */); }); @@ -155,7 +155,7 @@ Alternative, you can create a new command bus to handle each message with Handling Messages in Separate Processes --------------------------------------- -To handle messages in a forked process use the ``PcntlForkingHandler`` +To handle messages in a forked process, use the ``PcntlForkingHandler`` decorator. .. code-block:: php @@ -175,10 +175,10 @@ decorator. Forking is useful for memory management, but requires some consideration. For instance, database connections might need to be re-opened in the forked process. -In such cases, the best bet is to simply create the resources on demand. that's -why the ``TaticianHandler`` above takes a factory callable by default. +In such cases, create the resources on demand. That is why the +``TacticianHandler`` above takes a factory callable by default. In cases where a process fails to fork, a ``PMG\Queue\Exception\CouldNotFork`` exception will be thrown and the consumer will exit with an unsuccessful status -code. Your process manager (supervisord, upstart, systemd, etc) should be +code. Your process manager (supervisord, upstart, systemd, etc.) should be configured to restart the consumer when that happens. diff --git a/docs/index.rst b/docs/index.rst index fc0f6f6..0a5db0b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -6,11 +6,11 @@ PMG Queue ========= -``pmg/queue`` is a production ready queue framework that powers many internal +``pmg/queue`` is a production-ready queue framework that powers many internal projects at `PMG `_. -It's simple and extensible a number of features we've found to be the most -useful including automatic retries and multi-queue support. +It is simple and extensible, with features we have found most useful, +including automatic retries and multi-queue support. Contents @@ -28,7 +28,7 @@ Contents Installation & Examples ----------------------- -You should require the driver library of your choice with +You should require the driver library of your choice with `composer `_ rather than ``pmg/queue`` directly. If you're planning to use beanstalkd as your backend: @@ -37,8 +37,8 @@ you're planning to use beanstalkd as your backend: composer require pmg/queue-pheanstalk:~1.0 See the core `examples directory `_ -on the `pheanstalk examples `_ -for some code samples on gluing everything together. +and the `pheanstalk examples `_ +for code samples that show how everything fits together. READ THIS: Glossary & Core Concepts @@ -48,15 +48,15 @@ READ THIS: Glossary & Core Concepts processing. - A **producer** adds messages to the queue backend via a *driver* and a *router*. -- A **consumer** pulls messages out of the queue via *driver* and processes - them via *handlers*. -- A **driver** is PHP representation of the queue backend. There is an in memory +- A **consumer** pulls messages out of the queue via a *driver* and processes + them with *handlers*. +- A **driver** is a PHP representation of the queue backend. There is an in-memory driver included in this library as an example (and for testing), and an implementation of a `beanstalkd `_ driver `available `_. - A **router** is used by a producer to look up the correct queue for a message. - A **message handler** is used by the default *consumer* to actually do the work - of processing a message + of processing a message. - An **envelope** is used internally to wrap up messages with retry information as well as metadata specific to drivers. Users need not worry about this unless they are implementing their own *driver*. diff --git a/docs/messages.rst b/docs/messages.rst index 368d337..fe0b888 100644 --- a/docs/messages.rst +++ b/docs/messages.rst @@ -30,21 +30,21 @@ Example Message } } -Because messages are serialized to be put in a persistent backend they shouldn't -include objects that require state. In the example above the message just -contains a user's identifier rather than the full object. The :doc:`handler ` +Because messages are serialized and stored in a persistent backend, they should +not include objects that require state. In the example above, the message +contains only a user's identifier rather than the full object. The :doc:`handler ` would then look up the user. See :doc:`consumers` and :doc:`producers` for more information about handlers -and messages fit into the system as a whole. +and how messages fit into the system as a whole. Message Names ------------- To work with routing messages into certain queues in the :doc:`producers ` -we rely on *message names*. By default a message name is an objects full -qualified class name (FQCN). Should a message need a different name, implement -the `PMG\Queue\Message` which has a single method: `getName`. +we rely on *message names*. By default, a message name is an object's fully +qualified class name (FQCN). If a message needs a different name, implement +``PMG\Queue\Message``, which has a single method: ``getName``. .. code-block:: php diff --git a/docs/producers.rst b/docs/producers.rst index 779f044..b81534e 100644 --- a/docs/producers.rst +++ b/docs/producers.rst @@ -1,7 +1,7 @@ Producers ========= -Producers add messages to a driver backed for the :doc:`consumer ` to +Producers add messages to a driver backend for the :doc:`consumer ` to pick up and handle. .. php:interface:: Producer @@ -17,7 +17,7 @@ pick up and handle. The default producer implementation takes a driver and a router as its constructor arguments and uses the router (explained below) to send its messages -into a drivers specific queue. +into a driver-specific queue. .. code-block:: php @@ -36,9 +36,8 @@ into a drivers specific queue. Routers ------- -``pmg/queue`` is built with multi-queue support in in mind. To accomplish that -on the producer side of things an implementation of ``PMG\Queue\Router`` is -used. +``pmg/queue`` is built with multi-queue support in mind. To support that on the +producer side, an implementation of ``PMG\Queue\Router`` is used. .. php:interface:: Router @@ -46,14 +45,14 @@ used. .. php:method:: queueFor(PMG\\Queue\\Message $message) - Looks a queue name for a given message. + Looks up a queue name for a given message. :param $message: the message to route :returns: A string queue name if found, ``null`` otherwise. :rtype: string or null -Routing all Message to a Single Queue +Routing All Messages to a Single Queue """"""""""""""""""""""""""""""""""""" Use ``PMG\Queue\SimpleRouter``, which takes a queue name in the constructor @@ -64,7 +63,7 @@ and always returns it. getName()) { case 'TestMessage': @@ -28,7 +28,7 @@ $consumer = new Queue\DefaultConsumer( $driver, $handler, - new Queue\Retry\NeverSpec(), // allow never retry messages + new Queue\Retry\NeverSpec(), // disable retries new StreamLogger() ); diff --git a/src/Consumer.php b/src/Consumer.php index 24d9653..22f963c 100644 --- a/src/Consumer.php +++ b/src/Consumer.php @@ -14,7 +14,7 @@ namespace PMG\Queue; /** - * Consumer's pull messages out of the queue and execute them. + * Consumers pull messages out of the queue and execute them. * * @since 2.0 * @api @@ -35,16 +35,16 @@ public function run(string $queueName, ?MessageLifecycle $lifecycle=null) : int; /** * Consume a single job from the given queue. This will block until the - * job is competed then return. Implementations of this method MUST be + * job is completed and then return. Implementations of this method MUST be * safe to run in a loop. * * @param string $queueName The queue from which jobs will be consumed. * @param $lifecycle The message lifecycle to apply to any job run. * @throws Exception\MustStop if the executor or handler throws a must - * stop execption indicating a graceful stop is necessary + * stop exception indicating a graceful stop is necessary * @throws Exception\DriverError|Exception if anything goes wrong with the * underlying driver itself. - * @return boolean|null True if the a job was execute successfully. Null if + * @return boolean|null True if a job was executed successfully. Null if * no job was executed. See the logs. */ public function once(string $queueName, ?MessageLifecycle $lifecycle=null) : ?bool; diff --git a/src/Driver.php b/src/Driver.php index 9aa7e01..e5dd8b0 100644 --- a/src/Driver.php +++ b/src/Driver.php @@ -14,11 +14,11 @@ namespace PMG\Queue; /** - * Defines a driver backend for persistant queues. + * Defines a driver backend for persistent queues. * - * Drivers make no promises or guarantees about ordering of messages. Some drivers - * will be LIFO others will be FIFO and some have no ordering. Don't build systems - * that depend on those charactertistics. + * Drivers make no promises or guarantees about message ordering. Some drivers + * will be LIFO, others will be FIFO, and some have no ordering guarantees. + * Don't build systems that depend on those characteristics. * * Additionally, drivers know nothing about configuring a backend. If special steps * are required to create a queue, those should be done elsewhere. @@ -34,7 +34,7 @@ interface Driver * @param string $queueName The name of the queue to put the message in. * @param $message The message to add. * @throws Exception\DriverError when something goes wrong - * @return Envelope An envelop representing the message in the queue. + * @return Envelope An envelope representing the message in the queue. */ public function enqueue(string $queueName, object $message) : Envelope; @@ -51,7 +51,7 @@ public function dequeue(string $queueName) : ?Envelope; * Acknowledge a message as complete. * * @param string $queueName The queue from which the message came - * @param $envelope The message envelop -- should be the same instance + * @param $envelope The message envelope -- should be the same instance * returned by `dequeue` * @throws Exception\DriverError when something goes wrong * @return void @@ -61,19 +61,19 @@ public function ack(string $queueName, Envelope $envelope) : void; /** * Retry a job -- put it back in the queue for retrying. * - * @param string $queueName The queue from whcih the message came + * @param string $queueName The queue from which the message came * @param $envelope The message envelope -- should be the same instance * returned from `dequeue` * @throws Exception\DriverError when something goes wrong * @return Envelope The envelope that was retried. This can be the same - * envelope passed in or a new one depending on the drivers needs. + * envelope passed in or a new one depending on the driver's needs. */ public function retry(string $queueName, Envelope $envelope) : Envelope; /** - * Fail a job -- this called when no more retries can be attempted. + * Fail a job. This is called when no more retries can be attempted. * - * @param string $queueName The queue from whcih the message came + * @param string $queueName The queue from which the message came * @param $envelope The message envelope -- should be the same instance * returned from `dequeue` * @throws Exception\DriverError when something goes wrong diff --git a/src/Envelope.php b/src/Envelope.php index 2a53ba5..0b5a88d 100644 --- a/src/Envelope.php +++ b/src/Envelope.php @@ -47,11 +47,11 @@ public function delay() : int; public function unwrap() : object; /** - * Returns a new envelop with all the same attributes but an incremented + * Returns a new envelope with all the same attributes but an incremented * attempt count. * - * @param $delay The amount number of seconds the message should be delayed before retrying - * @return Envelop + * @param $delay The number of seconds the message should be delayed before retrying + * @return Envelope */ public function retry(int $delay=0) : Envelope; } diff --git a/src/Exception/SimpleMustStop.php b/src/Exception/SimpleMustStop.php index 2273e3d..c58ecde 100644 --- a/src/Exception/SimpleMustStop.php +++ b/src/Exception/SimpleMustStop.php @@ -14,7 +14,7 @@ namespace PMG\Queue\Exception; /** - * A simple must stop exception. Uses in tests. + * A simple must-stop exception used in tests. * * @since 2.0 */ diff --git a/src/Handler/Pcntl/Pcntl.php b/src/Handler/Pcntl/Pcntl.php index c9351bb..10d403f 100644 --- a/src/Handler/Pcntl/Pcntl.php +++ b/src/Handler/Pcntl/Pcntl.php @@ -16,7 +16,7 @@ use PMG\Queue\Exception\AbnormalExit; /** - * A very thin wrapper around the the `pcntl_*` functions and `exit` to deal + * A very thin wrapper around the `pcntl_*` functions and `exit` to deal * with forking processes. This exists simply so we can mock it and validate that * `PcntlForkingHandler` works. * @@ -35,8 +35,9 @@ public function __construct() } /** - * Fork a new process and return the current processes ID. In the parent thead - * this will be the child process' ID and the child thread will see a `0`. + * Fork a new process and return the current process's ID. In the parent + * thread, this will be the child process's ID, and the child thread will + * see a `0`. * * @return int */ @@ -46,12 +47,12 @@ public function fork() : int } /** - * Wait for the child process to finish and report wether its exit status - * was successful or not. If the child process exits normally this is - * will return a bool. If there was a non-normal exit (like a segfault) - * this will throw. + * Wait for the child process to finish and report whether it exited + * successfully. If the child process exits normally, this returns a + * result object. If there was a non-normal exit (like a segfault), this + * will throw. * - * @return bool True if the child existed successfully. + * @return bool True if the child exited successfully. */ public function wait($child) : WaitResult { @@ -66,7 +67,7 @@ public function wait($child) : WaitResult /** * Quit the current process by calling `exit`. The exit code is defined by - * whather the $succesful value is true. + * whether the `$successful` value is true. * * @param bool $successful If true `exit(0)` otherwise `exit(1)` * @return void diff --git a/src/Handler/PcntlForkingHandler.php b/src/Handler/PcntlForkingHandler.php index ad60ddd..350d5a7 100644 --- a/src/Handler/PcntlForkingHandler.php +++ b/src/Handler/PcntlForkingHandler.php @@ -26,8 +26,8 @@ * A message handler decorator that forks a child process to handle the message. * * Use with caution, and be aware that forking will mess with things like open - * connections and resources (sockets, files, etc). Best bet is to wrap this - * around a `CallableHandler` and bootstrap your entire application for each + * connections and resources (sockets, files, etc). The safest approach is to + * wrap this around a `CallableHandler` and bootstrap your entire application for each * message handled. Or implement your own `MessageHandler` that bootstraps the * entire application each time. * @@ -47,9 +47,9 @@ public function __construct(MessageHandler $wrapped, ?Pcntl $pcntl=null) /** * {@inheritdoc} - * This does not really deal with or log exceptions. It just swallows them - * and makes sure that the child process exits with an error (1). Should - * you want to do any specialized logging, that should happen in the wrapped + * This does not log exceptions directly. It swallows them and makes sure + * that the child process exits with an error (1). If you want to do any + * specialized logging, that should happen in the wrapped * `MessageHandler`. Just be sure to return `false` (the job failed) so it * can be retried. */ @@ -69,8 +69,8 @@ public function handle(object $message, array $options=[]) : PromiseInterface $promise = new Promise(function () use (&$promise, $child) { $result = $this->pcntl->wait($child); - // this happens when the promise is cancelled. We don't want to - // to try and change the promise to resolved if that happens. + // this happens when the promise is cancelled. We do not want to + // try to change the promise to resolved if that happens. if ($promise->getState() !== PromiseInterface::PENDING) { return; } diff --git a/src/MessageHandler.php b/src/MessageHandler.php index 99ac8af..6b803b6 100644 --- a/src/MessageHandler.php +++ b/src/MessageHandler.php @@ -26,12 +26,13 @@ interface MessageHandler * Handle a message. What that means depends on the implementation, but it * probably means interact with the user's system based on the given message. * - * @param $message That message to process. + * @param $message The message to process. * @param array $options A freeform set of options that may be passed from the * consumer. - * @return a promise object that resolves to `true` if the the handler was successful. - * or false if the handler failed. Since handlers may process messages - * outside the current thread, we're limited to a boolean here. + * @return A promise object that resolves to `true` if the handler was + * successful, or `false` if the handler failed. Since handlers may + * process messages outside the current thread, we're limited to a + * boolean here. */ public function handle(object $message, array $options=[]) : PromiseInterface; } diff --git a/src/MessageLifecycle.php b/src/MessageLifecycle.php index 9710e95..eb6f7d5 100644 --- a/src/MessageLifecycle.php +++ b/src/MessageLifecycle.php @@ -14,18 +14,18 @@ namespace PMG\Queue; /** - * Provides a way to hook into the life of a message as it moves through - * a consumer. + * Provides a way to hook into a message's lifecycle as it moves through a + * consumer. * - * This provides a way to extend the lifecycle of a message without tying you - * to a specific thing (like an event library, etc). + * This lets you extend a message's lifecycle without tying it to a specific + * system, such as an event library. * * @since 4.0 */ interface MessageLifecycle { /** - * Called when a message starts its processing in the consumer. + * Called when a consumer starts processing a message. * * @param $message The message that's starting * @param $consumer The consumer that's doing the work @@ -57,8 +57,9 @@ public function retrying(object $message, Consumer $consumer) : void; /** * Called when a message failed. * - * No details about the error are provided here because consumers, specifically - * the default consumer implementation may not have those details. For instance, + * No details about the error are provided here because consumers, + * specifically the default consumer implementation, may not have those + * details. For instance, * if a handler forks the child process will not pass any exception info up * to the parent. It's up to your handlers to deal with logging and accountability. * @@ -69,9 +70,9 @@ public function retrying(object $message, Consumer $consumer) : void; public function failed(object $message, Consumer $consumer) : void; /** - * Called when message processing was successful. + * Called when message processing succeeds. * - * @param $message The message that errored + * @param $message The message that succeeded * @param $consumer The consumer that did the work * @return void */ diff --git a/src/RetrySpec.php b/src/RetrySpec.php index 5d233ce..be959e0 100644 --- a/src/RetrySpec.php +++ b/src/RetrySpec.php @@ -23,15 +23,15 @@ interface RetrySpec { /** - * Given an envelop check whether or not it can be retried. + * Given an envelope, check whether or not it can be retried. * - * @param $env The envelop to check + * @param $env The envelope to check * @return boolean True if the message should be retried. */ public function canRetry(Envelope $env) : bool; /** - * Get the number of seconds before an envelop can be retried. + * Get the number of seconds before an envelope can be retried. * * @since 5.0.0 */ diff --git a/src/Serializer/NativeSerializer.php b/src/Serializer/NativeSerializer.php index 1502bc6..927ea75 100644 --- a/src/Serializer/NativeSerializer.php +++ b/src/Serializer/NativeSerializer.php @@ -22,7 +22,7 @@ use PMG\Queue\Signer\HmacSha256; /** - * A serializer implemtnation that uses PHP's native serialize and unserialize. + * A serializer implementation that uses PHP's native serialize and unserialize. * * @since 2.0 */ @@ -96,7 +96,7 @@ private function verifySignature(string $message) : string /** * Small wrapper around `unserialize` so we can pass in `$allowedClasses` - * if the PHP verison 7+ + * if the PHP version is 7+ * * @param string $str the string to unserialize * @return object|false diff --git a/src/Signer/Signer.php b/src/Signer/Signer.php index eabc0f0..499b8cb 100644 --- a/src/Signer/Signer.php +++ b/src/Signer/Signer.php @@ -14,8 +14,8 @@ namespace PMG\Queue\Signer; /** - * Sign or verify messages. This is used in conjuction with `NativeSerializer` - * for the most part. + * Sign or verify messages. This is used in conjunction with `NativeSerializer` + * in most cases. * * @since 4.0 */ @@ -24,8 +24,8 @@ interface Signer /** * Sign a message. * - * @param $message The message to signe - * @return a MAC that can be be associated with the message however the + * @param $message The message to sign + * @return string A MAC that can be associated with the message however the * caller sees fit. */ public function sign(string $message) : string; @@ -33,8 +33,9 @@ public function sign(string $message) : string; /** * Verify the message signature. * - * @param $signed The signed message - * @return True if the message signature is valid. + * @param $mac The MAC to verify + * @param $message The message that was signed + * @return bool True if the message signature is valid. */ public function verify(string $mac, string $message) : bool; } diff --git a/src/Signer/SodiumCryptoAuth.php b/src/Signer/SodiumCryptoAuth.php index ecf5c53..cae41f9 100644 --- a/src/Signer/SodiumCryptoAuth.php +++ b/src/Signer/SodiumCryptoAuth.php @@ -24,7 +24,7 @@ final class SodiumCryptoAuth implements Signer /** * Constructor. This tries to sign a dummy message immediately to validate - * that the key okay for libsodium. + * that the key works with libsodium. * * @param $key The key with which messages will be signed. */ diff --git a/test/integration/Serializer/HmacSha256NativeSerializerTest.php b/test/integration/Serializer/HmacSha256NativeSerializerTest.php index 07a2d40..1e8ea60 100644 --- a/test/integration/Serializer/HmacSha256NativeSerializerTest.php +++ b/test/integration/Serializer/HmacSha256NativeSerializerTest.php @@ -55,7 +55,7 @@ public function testSerializersCannotBeCreatedWithEmptyKeys() } /** - * @group regresion + * @group regression */ public function testMessagesSerializedInVersion2xCanStillBeUnserialized() { diff --git a/test/unit/DefaultEnvelopeTest.php b/test/unit/DefaultEnvelopeTest.php index 7d84ed7..fdae31f 100644 --- a/test/unit/DefaultEnvelopeTest.php +++ b/test/unit/DefaultEnvelopeTest.php @@ -19,7 +19,7 @@ class DefaultEnvelopeTest extends UnitTestCase { private $message; - public function testEnvelopeCannotBeCreatedWithAttempsLessThanZero() + public function testEnvelopeCannotBeCreatedWithAttemptsLessThanZero() { $this->expectException(InvalidArg::class); new DefaultEnvelope($this->message, -1); From 097a98df782e5eb4fa462bd090b370e75eec8063 Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 13:23:13 -0500 Subject: [PATCH 02/10] ALLI-21969: fix pcntl docblocks --- src/Handler/Pcntl/Pcntl.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Handler/Pcntl/Pcntl.php b/src/Handler/Pcntl/Pcntl.php index 10d403f..6fe0732 100644 --- a/src/Handler/Pcntl/Pcntl.php +++ b/src/Handler/Pcntl/Pcntl.php @@ -35,11 +35,10 @@ public function __construct() } /** - * Fork a new process and return the current process's ID. In the parent - * thread, this will be the child process's ID, and the child thread will - * see a `0`. + * Fork a new process using `pcntl_fork()`. * - * @return int + * @return int The child PID in the parent process, `0` in the child + * process, or `-1` on failure. */ public function fork() : int { @@ -52,7 +51,7 @@ public function fork() : int * result object. If there was a non-normal exit (like a segfault), this * will throw. * - * @return bool True if the child exited successfully. + * @return WaitResult The child process exit result. */ public function wait($child) : WaitResult { From 1c4cb7f1a2af42e8f6c4aef233051a0da8a5cf22 Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 13:30:15 -0500 Subject: [PATCH 03/10] ALLI-21969: polish docs markup --- docs/consumers.rst | 4 ++-- docs/handlers.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/consumers.rst b/docs/consumers.rst index 0a9ec24..76f91fb 100644 --- a/docs/consumers.rst +++ b/docs/consumers.rst @@ -35,8 +35,8 @@ which your :doc:`producer ` puts messages. with the underlying driver. Generally this happens if the persistent backend goes down or is unreachable. Without the driver, the consumer can't do its work. - :returns: True or false to indicate whether the message was handled successfully. - Null if no message was handled. + :returns: ``true`` or ``false`` to indicate whether the message was handled successfully. + ``null`` if no message was handled. :rtype: boolean or null .. php:method:: stop(int $code) diff --git a/docs/handlers.rst b/docs/handlers.rst index bd5aa58..beaa6c5 100644 --- a/docs/handlers.rst +++ b/docs/handlers.rst @@ -132,7 +132,7 @@ Use the same command bus with each message. $consumer = new DefaultConsumer($driver, $handler); Alternatively, you can create a new command bus to handle each message with -`CreatingTacticianHandler`. This is useful if you're using +``CreatingTacticianHandler``. This is useful if you're using :ref:`forking child processes ` to handle messages. .. code-block:: php From 786bd4a341da6a3b0b954cf1b77fb9eea1be4d27 Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 13:38:09 -0500 Subject: [PATCH 04/10] ALLI-21969: clarify serializer docblocks --- src/Serializer/NativeSerializer.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Serializer/NativeSerializer.php b/src/Serializer/NativeSerializer.php index 927ea75..9a669dc 100644 --- a/src/Serializer/NativeSerializer.php +++ b/src/Serializer/NativeSerializer.php @@ -29,8 +29,7 @@ final class NativeSerializer implements Serializer { /** - * Only applicable to PHP 7+. This is a set of allowed classes passed - * to the second argument of `unserialize`. + * A set of allowed classes passed to the second argument of `unserialize`. * * @var string[] */ @@ -96,9 +95,9 @@ private function verifySignature(string $message) : string /** * Small wrapper around `unserialize` so we can pass in `$allowedClasses` - * if the PHP version is 7+ + * when it is configured. * - * @param string $str the string to unserialize + * @param string $str The string to unserialize * @return object|false */ private function doUnserialize($str) From 67c1933dd65e8821935273a6ddeafab9c6e08ca1 Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 13:44:04 -0500 Subject: [PATCH 05/10] ALLI-21969: fix docs driver references --- docs/drivers.rst | 5 +++-- docs/handlers.rst | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/drivers.rst b/docs/drivers.rst index cbb9eec..145afd7 100644 --- a/docs/drivers.rst +++ b/docs/drivers.rst @@ -10,8 +10,9 @@ Drivers ------- Drivers are the queue backend hidden behind the ``PMG\Queue\Driver`` interface. -``pmg/queue`` comes with two built-in drivers: *memory* and *pheanstalk* -(beanstalkd). +The core ``pmg/queue`` library ships with a single built-in driver: *memory*. +PMG also maintains an external *pheanstalk* (beanstalkd) driver in the +``pmg/queue-pheanstalk`` package. Drivers have methods for enqueuing and dequeueing messages as well as methods for acknowledging that a message is complete, retrying a message, or marking a message diff --git a/docs/handlers.rst b/docs/handlers.rst index beaa6c5..12bb43b 100644 --- a/docs/handlers.rst +++ b/docs/handlers.rst @@ -176,7 +176,7 @@ decorator. Forking is useful for memory management, but requires some consideration. For instance, database connections might need to be re-opened in the forked process. In such cases, create the resources on demand. That is why the -``TacticianHandler`` above takes a factory callable by default. +``CreatingTacticianHandler`` above takes a factory callable by default. In cases where a process fails to fork, a ``PMG\Queue\Exception\CouldNotFork`` exception will be thrown and the consumer will exit with an unsuccessful status From ed10b749cabe2eca712682686c9a255327f69ef5 Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 13:53:25 -0500 Subject: [PATCH 06/10] ALLI-21969: sync handler docs with api --- docs/handlers.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/handlers.rst b/docs/handlers.rst index 12bb43b..c179178 100644 --- a/docs/handlers.rst +++ b/docs/handlers.rst @@ -14,12 +14,13 @@ figure out how to deal with each message appropriately. An object that can handle (process or act upon) a single message. - .. php:method:: handle(PMG\\Queue\\Message $handle, array $options=[]) + .. php:method:: handle(object $message, array $options=[]) - :param $handle: The message to handle. + :param $message: The message to handle. :param $options: A set of options from the consumer. - :return: A boolean indicating whether the message was handled successfully. - :rtype: boolean + :return: A promise resolving to a boolean indicating whether the message + was handled successfully. + :rtype: PromiseInterface Callable Handler From 12a59f8a523ab6bc8b51c826e918a89e89052ac9 Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 13:57:29 -0500 Subject: [PATCH 07/10] ALLI-21969: fix serializer return docs --- src/Serializer/NativeSerializer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Serializer/NativeSerializer.php b/src/Serializer/NativeSerializer.php index 9a669dc..3b28ab9 100644 --- a/src/Serializer/NativeSerializer.php +++ b/src/Serializer/NativeSerializer.php @@ -98,7 +98,8 @@ private function verifySignature(string $message) : string * when it is configured. * * @param string $str The string to unserialize - * @return object|false + * @return mixed Any value returned by `unserialize()` + * @throws SerializationError If unserialization fails */ private function doUnserialize($str) { From 12d6a32606f94fad8fe558f7c23000503a27643d Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 14:02:03 -0500 Subject: [PATCH 08/10] ALLI-21969: fix handler phpdoc return type --- src/MessageHandler.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MessageHandler.php b/src/MessageHandler.php index 6b803b6..a045e37 100644 --- a/src/MessageHandler.php +++ b/src/MessageHandler.php @@ -29,7 +29,8 @@ interface MessageHandler * @param $message The message to process. * @param array $options A freeform set of options that may be passed from the * consumer. - * @return A promise object that resolves to `true` if the handler was + * @return PromiseInterface A promise object that resolves to `true` if the + * handler was * successful, or `false` if the handler failed. Since handlers may * process messages outside the current thread, we're limited to a * boolean here. From f3a576c184429c1d7b8680f835f2e50fc3990c23 Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 14:07:54 -0500 Subject: [PATCH 09/10] ALLI-21969: qualify handler docs return type --- docs/handlers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/handlers.rst b/docs/handlers.rst index c179178..79938e7 100644 --- a/docs/handlers.rst +++ b/docs/handlers.rst @@ -20,7 +20,7 @@ figure out how to deal with each message appropriately. :param $options: A set of options from the consumer. :return: A promise resolving to a boolean indicating whether the message was handled successfully. - :rtype: PromiseInterface + :rtype: GuzzleHttp\\Promise\\PromiseInterface Callable Handler From 5b8f84ab6d46ad9a96af6d200ff0db923419c3a5 Mon Sep 17 00:00:00 2001 From: Noah Date: Wed, 18 Mar 2026 14:23:05 -0500 Subject: [PATCH 10/10] ALLI-21969: clarify handler example assumptions --- docs/handlers.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/handlers.rst b/docs/handlers.rst index 79938e7..fec825a 100644 --- a/docs/handlers.rst +++ b/docs/handlers.rst @@ -27,7 +27,8 @@ Callable Handler ---------------- The simplest handler could just be a callable that invokes the provided callback -with the message. +with the message. This example assumes your messages implement +``PMG\Queue\Message`` because it relies on ``getName()``. .. code-block:: php