@@ -1142,7 +1142,8 @@ $subscriberAccessorRepository = new MetadataSubscriberAccessorRepository([
11421142Now we can create the subscription engine and plug together the necessary services.
11431143The message loader is needed to load the messages, the Subscription Store to store the subscription state
11441144and we need the subscriber accessor repository. Optionally, we can also pass a retry strategy.
1145- Finally, if we want to use the cleanup feature, we need to pass the cleanup handlers.
1145+ If we want to use the cleanup feature, we need to pass the cleanup handlers.
1146+ Finally, we can pass an event dispatcher to hook into the engine with own listeners.
11461147
11471148``` php
11481149use Doctrine\DBAL\Connection;
@@ -1153,6 +1154,7 @@ use Patchlevel\EventSourcing\Subscription\Engine\MessageLoader;
11531154use Patchlevel\EventSourcing\Subscription\RetryStrategy\RetryStrategyRepository;
11541155use Patchlevel\EventSourcing\Subscription\Store\DoctrineSubscriptionStore;
11551156use Patchlevel\EventSourcing\Subscription\Subscriber\MetadataSubscriberAccessorRepository;
1157+ use Symfony\Component\EventDispatcher\EventDispatcher;
11561158
11571159/**
11581160 * @var MessageLoader $messageLoader
@@ -1169,6 +1171,34 @@ $subscriptionEngine = new DefaultSubscriptionEngine(
11691171 $retryStrategyRepository, // optional, if not set the default retry strategy is used
11701172 $logger, // optional
11711173 new DefaultCleaner([new DbalCleanupTaskHandler($projectionConnection)]), // optional but required if you want to use the cleanup feature
1174+ new EventDispatcher(), // optional, to hook into the engine with own listeners
1175+ );
1176+ ```
1177+ ### Engine Events
1178+
1179+ The ` DefaultSubscriptionEngine ` dispatches events during processing on the passed event dispatcher.
1180+ You can register your own listeners to hook into the engine, for example for logging, metrics or batching.
1181+
1182+ | Event | Description |
1183+ | --------------------------| ----------------------------------------------------------------------|
1184+ | ` OnCommand ` | A command was passed to the engine for execution |
1185+ | ` OnSubscriptions ` | The engine determined the subscriptions for the current command |
1186+ | ` OnHandleMessage ` | A message is about to be passed to a subscriber |
1187+ | ` OnHandleMessageSuccess ` | A message was successfully handled by a subscriber |
1188+ | ` OnHandleMessageError ` | An error occurred while a subscriber was handling a message |
1189+ | ` OnProcessingFinished ` | The engine finished processing the stream (ended or limit reached) |
1190+ | ` OnResult ` | The engine finished the command and returns the result |
1191+
1192+ ``` php
1193+ use Patchlevel\EventSourcing\Subscription\Engine\Event\OnHandleMessageError;
1194+ use Symfony\Component\EventDispatcher\EventDispatcher;
1195+
1196+ $eventDispatcher = new EventDispatcher();
1197+ $eventDispatcher->addListener(
1198+ OnHandleMessageError::class,
1199+ static function (OnHandleMessageError $event): void {
1200+ // own error handling like logging or metrics
1201+ },
11721202);
11731203```
11741204### Catch up Subscription Engine
@@ -1249,15 +1279,20 @@ Especially in combination with the `CatchUpSubscriptionEngine` and `ThrowOnError
12491279
12501280## Usage
12511281
1252- The Subscription Engine has a few methods needed to use it effectively.
1253- A ` SubscriptionEngineCriteria ` can be passed to all of these methods to filter the respective subscriptions.
1282+ The Subscription Engine is controlled with command objects.
1283+ Each command is passed to the ` execute ` method, which returns a ` Result ` with the errors that occurred.
1284+ Every command accepts ` ids ` and ` groups ` parameters to filter the subscriptions the command should be applied to.
12541285
12551286``` php
1256- use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
1287+ use Patchlevel\EventSourcing\Subscription\Engine\Command\Run;
1288+ use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
12571289
1258- $criteria = new SubscriptionEngineCriteria(
1259- ids: ['profile_1', 'welcome_email'],
1260- groups: ['default'],
1290+ /** @var SubscriptionEngine $subscriptionEngine */
1291+ $subscriptionEngine->execute(
1292+ new Run(
1293+ ids: ['profile_1', 'welcome_email'],
1294+ groups: ['default'],
1295+ ),
12611296);
12621297```
12631298
@@ -1272,52 +1307,62 @@ In this step, the subscription engine also tries to call the `setup` method if a
12721307After the setup process, the subscription is set to booting or active.
12731308
12741309``` php
1310+ use Patchlevel\EventSourcing\Subscription\Engine\Command\Setup;
12751311use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
1276- use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
12771312
12781313/** @var SubscriptionEngine $subscriptionEngine */
1279- $subscriptionEngine->setup (new SubscriptionEngineCriteria ());
1314+ $subscriptionEngine->execute (new Setup ());
12801315```
12811316
12821317::: tip
1283- You can skip the booting step with the second boolean parameter named ` skipBooting ` .
1318+ You can skip the booting step with the ` skipBooting ` parameter: ` new Setup( skipBooting: true) ` .
12841319:::
12851320
12861321### Boot
12871322
1288- You can boot the subscriptions with the ` boot ` method .
1323+ You can boot the subscriptions with the ` Boot ` command .
12891324All booting subscriptions will catch up to the current event stream.
12901325After the boot process, the subscription is set to active or finished.
12911326
12921327``` php
1328+ use Patchlevel\EventSourcing\Subscription\Engine\Command\Boot;
12931329use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
1294- use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
12951330
12961331/** @var SubscriptionEngine $subscriptionEngine */
1297- $subscriptionEngine->boot (new SubscriptionEngineCriteria ());
1332+ $subscriptionEngine->execute (new Boot ());
12981333```
1334+
1335+ ::: tip
1336+ You can limit the number of processed messages with the ` limit ` parameter: ` new Boot(limit: 100) ` .
1337+ :::
1338+
12991339### Run
13001340
13011341All active subscriptions are continued and updated here.
13021342
13031343``` php
1344+ use Patchlevel\EventSourcing\Subscription\Engine\Command\Run;
13041345use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
1305- use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
13061346
13071347/** @var SubscriptionEngine $subscriptionEngine */
1308- $subscriptionEngine->run (new SubscriptionEngineCriteria ());
1348+ $subscriptionEngine->execute (new Run ());
13091349```
1350+
1351+ ::: tip
1352+ You can limit the number of processed messages with the ` limit ` parameter: ` new Run(limit: 100) ` .
1353+ :::
1354+
13101355### Teardown
13111356
13121357If subscriptions are detached, they can be cleaned up here.
13131358The subscription engine also tries to call the ` teardown ` method if available.
13141359
13151360``` php
1361+ use Patchlevel\EventSourcing\Subscription\Engine\Command\Teardown;
13161362use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
1317- use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
13181363
13191364/** @var SubscriptionEngine $subscriptionEngine */
1320- $subscriptionEngine->teardown (new SubscriptionEngineCriteria ());
1365+ $subscriptionEngine->execute (new Teardown ());
13211366```
13221367### Remove
13231368
@@ -1326,23 +1371,23 @@ An attempt is made to call the `teardown` method if available.
13261371But the entry will still be removed if it doesn't work.
13271372
13281373``` php
1374+ use Patchlevel\EventSourcing\Subscription\Engine\Command\Remove;
13291375use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
1330- use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
13311376
13321377/** @var SubscriptionEngine $subscriptionEngine */
1333- $subscriptionEngine->remove (new SubscriptionEngineCriteria ());
1378+ $subscriptionEngine->execute (new Remove ());
13341379```
13351380### Reactivate
13361381
13371382If a subscription had an error or is outdated, you can reactivate it.
13381383As a result, the subscription gets in the last status again.
13391384
13401385``` php
1386+ use Patchlevel\EventSourcing\Subscription\Engine\Command\Reactivate;
13411387use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
1342- use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
13431388
13441389/** @var SubscriptionEngine $subscriptionEngine */
1345- $subscriptionEngine->reactivate (new SubscriptionEngineCriteria ());
1390+ $subscriptionEngine->execute (new Reactivate ());
13461391```
13471392### Pause
13481393
@@ -1351,38 +1396,39 @@ The subscription will then no longer be managed by the subscription engine.
13511396You can reactivate the subscription if you want so that it continues.
13521397
13531398``` php
1399+ use Patchlevel\EventSourcing\Subscription\Engine\Command\Pause;
13541400use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
1355- use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
13561401
13571402/** @var SubscriptionEngine $subscriptionEngine */
1358- $subscriptionEngine->pause (new SubscriptionEngineCriteria ());
1403+ $subscriptionEngine->execute (new Pause ());
13591404```
1360- ### Status
1405+ ### Refresh
13611406
1362- To get the current status of all subscriptions, you can get them using the ` subscriptions ` method.
1407+ If you change the metadata of a subscriber in the code (e.g. ` runMode ` , ` group ` or ` cleanupTasks ` ),
1408+ you can use the ` Refresh ` command to update the existing subscriptions in the store.
13631409
13641410``` php
1411+ use Patchlevel\EventSourcing\Subscription\Engine\Command\Refresh;
13651412use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
1366- use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
13671413
13681414/** @var SubscriptionEngine $subscriptionEngine */
1369- $subscriptions = $subscriptionEngine->subscriptions(new SubscriptionEngineCriteria());
1370-
1371- foreach ($subscriptions as $subscription) {
1372- echo $subscription->status()->value;
1373- }
1415+ $subscriptionEngine->execute(new Refresh());
13741416```
1375- ### Refresh
1417+ ### Status
13761418
1377- If you change the metadata of a subscriber in the code (e.g. ` runMode ` , ` group ` or ` cleanupTasks ` ),
1378- you can use the ` refresh ` method to update the existing subscriptions in the store .
1419+ To get the current status of all subscriptions, you can get them using the ` subscriptions ` method.
1420+ A ` SubscriptionEngineCriteria ` can be passed to filter the subscriptions .
13791421
13801422``` php
13811423use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngine;
13821424use Patchlevel\EventSourcing\Subscription\Engine\SubscriptionEngineCriteria;
13831425
13841426/** @var SubscriptionEngine $subscriptionEngine */
1385- $subscriptionEngine->refresh(new SubscriptionEngineCriteria());
1427+ $subscriptions = $subscriptionEngine->subscriptions(new SubscriptionEngineCriteria());
1428+
1429+ foreach ($subscriptions as $subscription) {
1430+ echo $subscription->status()->value;
1431+ }
13861432```
13871433## Learn more
13881434
0 commit comments