From 4d20eee67caab4a25ef268917ce42d281a75c15e Mon Sep 17 00:00:00 2001 From: Gowri Date: Sat, 29 Jun 2024 14:22:55 +0930 Subject: [PATCH 1/4] :memo: update docs --- README.md | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index ff95cad..7a93c37 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Magento Asynchronous Events -[![Integration Test](https://github.com/aligent/magento-async-events/actions/workflows/integration-tests.yml/badge.svg)](https://github.com/aligent/magento-async-events/actions/workflows/integration-tests.yml) -[![REST](https://github.com/aligent/magento-async-events/actions/workflows/api-functional-tests.yml/badge.svg)](https://github.com/aligent/magento-async-events/actions/workflows/api-functional-tests.yml) +[![Integration Test](https://github.com/mage-os/mageos-async-events/actions/workflows/integration-tests.yml/badge.svg)](https://github.com/mage-os/mageos-async-events/actions/workflows/integration-tests.yml) +[![REST](https://github.com/mage-os/mageos-async-events/actions/workflows/api-functional-tests.yml/badge.svg)](https://github.com/mage-os/mageos-async-events/actions/workflows/api-functional-tests.yml) A framework for reliably handling asynchronous events with Magento. @@ -9,28 +9,16 @@ A framework for reliably handling asynchronous events with Magento. * **Flexible**: Decoupling events and dispatches provide greater flexibility in message modelling. * **Scalable**: Handles back pressure and provides an asynchronous failover model automatically. -## Support - -| Async Events | Magento 2.3.x | >= Magento 2.4.0 <= Magento 2.4.3 | >= Magento 2.4.4 | -|--------------|--------------------|-----------------------------------|--------------------| -| 2.x | :white_check_mark: | :white_check_mark: | :x: | -| 3.x | :x: | :x: | :white_check_mark: | - ## Installation -``` -composer config repositories.mageos-async-events git https://github.com/mage-os/mageos-async-events.git -composer require mage-os/mageos-async-events -``` - -If you run into an error like "Could not find a version of package mage-os/mageos-async-events matching your minimum-stability (stable).", run this command instead: -``` -composer require mage-os/mageos-async-events @dev +```shell +$ composer require mage-os/mageos-async-events ``` Install the module: -``` -bin/magento setup:upgrade + +```shell +$ bin/magento setup:upgrade ``` ## Usage @@ -55,7 +43,7 @@ Create a new `async_events.xml` under a module's `etc/` directory. #### HTTP Subscription ```shell -curl --location --request POST 'https://m2.dev.aligent.consulting:44356/rest/V1/async_event' \ +curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \ --header 'Authorization: Bearer TOKEN' \ --header 'Content-Type: application/json' \ --data-raw '{ @@ -72,15 +60,15 @@ curl --location --request POST 'https://m2.dev.aligent.consulting:44356/rest/V1/ Requires the [EventBridge Notifier](https://github.com/aligent/magento2-eventbridge-notifier) ```shell -curl --location --request POST 'https://m2.dev.aligent.consulting:44356/rest/V1/async_event' \ +curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \ --header 'Authorization: Bearer TOKEN' \ --header 'Content-Type: application/json' \ --data-raw '{ "asyncEvent": { "event_name": "sales.order.created", - "recipient_url": "arn:aws:events:ap-southeast-2:005158166381:rule/Test.EventBridge.Rule", + "recipient_url": "arn:aws:events:ap-southeast-2:005158166381:rule/default", "verification_token": "aIW0G9n3*9wN", - "metadata": "event_bridge" + "metadata": "eventbridge" } }' ``` @@ -112,10 +100,6 @@ bin/magento queue:consumer:start event.trigger.consumer bin/magento queue:consumer:start event.retry.consumer ``` -## Advanced Usage -Refer to the [Wiki](https://github.com/aligent/magento-async-events/wiki) - - # Features ## Trace @@ -245,3 +229,11 @@ Search all events with the order increment id starting with `CK` and status succ To turn off asynchronous event indexing visit Admin > Stores > Settings > Configuration > Advanced > System > Async Events and disable `Enable Asynchronous Events Indexing`. + +## Support + +| Async Events | Magento 2.3.x | >= Magento 2.4.0 <= Magento 2.4.3 | >= Magento 2.4.4 | +|--------------|--------------------|-----------------------------------|--------------------| +| 2.x | :white_check_mark: | :white_check_mark: | :x: | +| 3.x | :x: | :x: | :white_check_mark: | +| 4.x | :x: | :x: | :white_check_mark: | From 8813fa879b10dadc6a74f8bf5ef2e4b1010c5006 Mon Sep 17 00:00:00 2001 From: Gowri Date: Sat, 29 Jun 2024 14:31:44 +0930 Subject: [PATCH 2/4] :memo: update docs --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a93c37..3cbf169 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,10 @@ Create a new `async_events.xml` under a module's `etc/` directory. ``` -### Create Subscription +### Create a Subscription + +> [!TIP] +> To view all available event sinks, check out [Async Event Sinks](https://github.com/mage-os/mageos-async-events-sinks) #### HTTP Subscription ```shell @@ -57,7 +60,7 @@ curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \ ``` #### Amazon EventBridge Subscription -Requires the [EventBridge Notifier](https://github.com/aligent/magento2-eventbridge-notifier) +Requires the [AWS Sinks](https://github.com/mage-os/mageos-async-events-aws) ```shell curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \ From 8bd548ec66411e30d14e5196fb8c23e2565f5e0e Mon Sep 17 00:00:00 2001 From: Gowri Date: Sat, 29 Jun 2024 14:56:18 +0930 Subject: [PATCH 3/4] :memo: update docs --- README.md | 76 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 3cbf169..ea2b6ad 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,10 @@ Create a new `async_events.xml` under a module's `etc/` directory. ### Create a Subscription > [!TIP] -> To view all available event sinks, check out [Async Event Sinks](https://github.com/mage-os/mageos-async-events-sinks) +> To view all available event sinks, check out [Async Event Sinks](https://github.com/mage-os/mageos-async-events-sinks) + +#### HTTP -#### HTTP Subscription ```shell curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \ --header 'Authorization: Bearer TOKEN' \ @@ -53,14 +54,15 @@ curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \ "asyncEvent": { "event_name": "sales.order.created", "recipient_url": "https://example.com/order_created", - "verification_token": "fD03@NpYbXYg", + "verification_token": "supersecret", "metadata": "http" } }' ``` -#### Amazon EventBridge Subscription -Requires the [AWS Sinks](https://github.com/mage-os/mageos-async-events-aws) +#### Amazon EventBridge + +Requires the [AWS Sinks](https://github.com/mage-os/mageos-async-events-aws) package ```shell curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \ @@ -69,30 +71,33 @@ curl --location --request POST 'https://test.mageos.dev/rest/V1/async_event' \ --data-raw '{ "asyncEvent": { "event_name": "sales.order.created", - "recipient_url": "arn:aws:events:ap-southeast-2:005158166381:rule/default", - "verification_token": "aIW0G9n3*9wN", + "recipient_url": "arn:aws:events:ap-southeast-2:ACCOUNT_ID:rule/BUS_NAME", + "verification_token": "supersecret", "metadata": "eventbridge" } }' ``` ### Dispatch an asynchronous event + ```php +use \MageOS\AsyncEvents\Model\AsyncEventPublisher; + +// ... + +public function __construct(private readonly AsyncEventPublisher $asyncEventPublisher) {} + public function execute(Observer $observer): void { - /** @var Order $object */ - $object = $observer->getEvent()->getData('order'); + /** @var Order $order */ + $order = $observer->getData('order'); // arguments are the inputs required by the service class in the asynchronous // event definition in async_events.xml // e.g: Magento\Sales\Api\OrderRepositoryInterface::get - $arguments = ['id' => $object->getId()]; - $data = ['sales.order.created', $this->json->serialize($arguments)]; + $message = ['id' => $order->getId()]; - $this->publisher->publish( - QueueMetadataInterface::EVENT_QUEUE, - $data - ); + $this->asyncEventPublisher->publish('sales.order.created', $message); } ``` @@ -116,20 +121,25 @@ is also available to view for investigation purposes. ## Retries -Events are automatically retried with exponential back off. The default retry limit is 5. The maximum backoff is +Events are automatically retried with quadratic back off. The default retry limit is 5. The maximum backoff is 60 seconds. -The exponential backoff is calculated as `min(60, pow($deathCount, 2));` +> [!IMPORTANT] +> RabbitMQ is required for retries with back off. If you are using DB queues then quadratic back off is +> not available, and you will have to implement your own `\MageOS\AsyncEvents\Api\RetryManagementInterface` + +The quadratic backoff is calculated as `min(60, pow($deathCount, 2));` -| Attempt | Backoff | -|---------|-------------| -| 1 | 1 second | -| 2 | 4 seconds | -| 3 | 9 seconds | -| 4 | 16 seconds | -| 5 | 25 seconds | +| Attempt | Backoff | +|---------|------------| +| 1 | 1 second | +| 2 | 4 seconds | +| 3 | 9 seconds | +| 4 | 16 seconds | +| 5 | 25 seconds | -To change the default retry limit visit Admin > Stores > Settings > Configuration > Advanced > System > Async Events and update `Maximum Deaths`. +To change the default retry limit visit Admin > Stores > Settings > Configuration > Advanced > System > Async Events and +update `Maximum Deaths`. ![Retry Limit Config Page](docs/retry_limit_config.png) @@ -142,9 +152,11 @@ Replays start a new chain of delivery attempts and will respect the same retry m ## Lucene Query Syntax -All events are indexed in Elasticsearch by default. This allows you to search through events including the event payload! +All events are indexed in Elasticsearch by default. This allows you to search through events including the event +payload! -The module supports [Lucene Query Syntax](https://lucene.apache.org/core/2_9_4/queryparsersyntax.html) to query event data like attributes. +The module supports [Lucene Query Syntax](https://lucene.apache.org/core/2_9_4/queryparsersyntax.html) to query event +data like attributes. The following attributes are available across all asynchronous events. @@ -155,7 +167,9 @@ event_name success created ``` + The following attributes differ between asynchronous event types. + ``` data ``` @@ -163,6 +177,7 @@ data ### Examples Assuming you have the following events configured + ``` customer.created customer.updated @@ -173,7 +188,9 @@ shipment.created shipment.updated shipment.deleted ``` + You can query all customer events by using a wildcard like `event_name: customer.*` which matches the following events + ``` customer.created customer.updated @@ -181,6 +198,7 @@ customer.deleted ``` You can query all created events like `*.created` which matches the following events + ``` customer.created sales.order.created @@ -192,9 +210,11 @@ You can further narrow down using the other available attributes such as status The following query returns all customer events which have failed. `customer.* AND success: false` -You can combine complex lucene queries to fetch event history and then export them via the admin grid as a csv if you wish. +You can combine complex lucene queries to fetch event history and then export them via the admin grid as a csv if you +wish. #### Searching inside event payloads + Searching an event payload depends on what event you are searching on. For the following example event payload, four properties are indexed as attributes. Therefore, you can query on From 493e07ee96181fb559be4970ff761d9c19920c0a Mon Sep 17 00:00:00 2001 From: Gowri Date: Sat, 29 Jun 2024 15:05:54 +0930 Subject: [PATCH 4/4] :memo: update docs --- Service/AsyncEvent/RetryManager.php | 2 +- Test/Integration/FailoverTopologyTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Service/AsyncEvent/RetryManager.php b/Service/AsyncEvent/RetryManager.php index b89f4fe..141042c 100644 --- a/Service/AsyncEvent/RetryManager.php +++ b/Service/AsyncEvent/RetryManager.php @@ -165,7 +165,7 @@ private function assertDelayQueue(int $backoff, string $queueName, string $retry } /** - * Exponential back off. Change the exponent to determine cubical back off or quartic back off + * Quadratic back off: x^2 * * @param int $deathCount * @return int diff --git a/Test/Integration/FailoverTopologyTest.php b/Test/Integration/FailoverTopologyTest.php index 8899b61..7832071 100644 --- a/Test/Integration/FailoverTopologyTest.php +++ b/Test/Integration/FailoverTopologyTest.php @@ -78,7 +78,7 @@ public function testDelayQueueCreation(): void }, $bindings); /** - * Exponential backoff delay queues + * Quadratic backoff delay queues */ $this->assertContains('event.retry.init', $destinations); $this->assertContains('event.delay.4', $destinations);