Making sure events get handled in the right order | laravel-event-sourcing | Spatie

 SPATIE

  Laravel Event Sourcing
=========================

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Laravel-event-sourcing](https://spatie.be/docs/laravel-event-sourcing/v7)  Using-projectors  Making sure events get handled in the right order

 Version   v7   v6   v5   v4   v3   v2   v1

 Other versions for crawler [v7](https://spatie.be/docs/laravel-event-sourcing/v7) [v6](https://spatie.be/docs/laravel-event-sourcing/v6) [v5](https://spatie.be/docs/laravel-event-sourcing/v5) [v4](https://spatie.be/docs/laravel-event-sourcing/v4) [v3](https://spatie.be/docs/laravel-event-sourcing/v3) [v2](https://spatie.be/docs/laravel-event-sourcing/v2) [v1](https://spatie.be/docs/laravel-event-sourcing/v1)

- [ Introduction ](https://spatie.be/docs/laravel-event-sourcing/v7/introduction)
- [ Support us ](https://spatie.be/docs/laravel-event-sourcing/v7/support-us)
- [ Requirements ](https://spatie.be/docs/laravel-event-sourcing/v7/requirements)
- [ Installation &amp; setup ](https://spatie.be/docs/laravel-event-sourcing/v7/installation-setup)
- [ Questions and issues ](https://spatie.be/docs/laravel-event-sourcing/v7/questions-issues)
- [ Changelog ](https://spatie.be/docs/laravel-event-sourcing/v7/changelog)
- [ Upgrading ](https://spatie.be/docs/laravel-event-sourcing/v7/upgrading)
- [ Resources and alternatives ](https://spatie.be/docs/laravel-event-sourcing/v7/resources-and-alternatives)
- [ About us ](https://spatie.be/docs/laravel-event-sourcing/v7/about-us)

Getting familiar with event sourcing
------------------------------------

- [ Introduction ](https://spatie.be/docs/laravel-event-sourcing/v7/getting-familiar-with-event-sourcing/introduction)
- [ The traditional application ](https://spatie.be/docs/laravel-event-sourcing/v7/getting-familiar-with-event-sourcing/the-traditional-application)
- [ Using projectors to transform events ](https://spatie.be/docs/laravel-event-sourcing/v7/getting-familiar-with-event-sourcing/using-projectors-to-transform-events)
- [ Using aggregates to make decisions based on the past ](https://spatie.be/docs/laravel-event-sourcing/v7/getting-familiar-with-event-sourcing/using-aggregates-to-make-decisions-based-on-the-past)

Using projectors
----------------

- [ Writing your first projector ](https://spatie.be/docs/laravel-event-sourcing/v7/using-projectors/writing-your-first-projector)
- [ Creating and registering projectors ](https://spatie.be/docs/laravel-event-sourcing/v7/using-projectors/creating-and-configuring-projectors)
- [ Making sure events get handled in the right order ](https://spatie.be/docs/laravel-event-sourcing/v7/using-projectors/making-sure-events-get-handled-in-the-right-order)
- [ Thinking in events ](https://spatie.be/docs/laravel-event-sourcing/v7/using-projectors/thinking-in-events)

Using reactors
--------------

- [ Writing your first reactor ](https://spatie.be/docs/laravel-event-sourcing/v7/using-reactors/writing-your-first-reactor)
- [ Creating and configuring reactors ](https://spatie.be/docs/laravel-event-sourcing/v7/using-reactors/creating-and-configuring-reactors)

Using aggregates
----------------

- [ Writing your first aggregate ](https://spatie.be/docs/laravel-event-sourcing/v7/using-aggregates/writing-your-first-aggregate)
- [ Creating and configuring aggregates ](https://spatie.be/docs/laravel-event-sourcing/v7/using-aggregates/creating-and-configuring-aggregates)
- [ Testing aggregates ](https://spatie.be/docs/laravel-event-sourcing/v7/using-aggregates/testing-aggregates)
- [ Snapshots ](https://spatie.be/docs/laravel-event-sourcing/v7/using-aggregates/snapshots)

Advanced usage
--------------

- [ Preparing events ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/preparing-events)
- [ Replaying events ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/replaying-events)
- [ Storing metadata ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/storing-metadata)
- [ Handling exceptions ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/handling-exceptions)
- [ Discovering projectors and reactors ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/discovering-projectors-and-reactors)
- [ Using your own event storage model ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/using-your-own-event-storage-model)
- [ Using your own event storage repository ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/using-your-own-event-storage-repository)
- [ Using your own event serializer ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/using-your-own-event-serializer)
- [ Using aliases for stored event classes ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/using-aliases-for-stored-event-classes)
- [ Adding and Removing Projectors and Reactors ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/adding-and-removing-projectors-and-reactors)
- [ Aggregate Partials ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/aggregate-partials)
- [ Event Queries ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/event-queries)
- [ Commands ](https://spatie.be/docs/laravel-event-sourcing/v7/advanced-usage/commands)

 Making sure events get handled in the right order
=================================================

###  On this page

1. [ Handling events in a queue ](#content-handling-events-in-a-queue)
2. [ Tweaking projector order ](#content-tweaking-projector-order)
3. [ Want to know more? ](#content-want-to-know-more)

By default all events are handled in a synchronous manner. This means that if you fire off an event in a request, all projectors will get called in the same request.

Handling events in a queue
--------------------------------------------------------------------------------------------------------------------------------------

A queue can be used to guarantee that all events get passed to projectors in the right order. If you want a projector to handle events in a queue then simply add the `Illuminate\Contracts\Queue\ShouldQueue` interface to your projector just like you would a Job.

A useful rule of thumb is that if your projectors aren't producing data that is consumed in the same request as the events are fired, you should let your projector implement `Illuminate\Contracts\Queue\ShouldQueue`.

You can set the name of the queue connection in the `queue` key of the `event-sourcing` config file. You should make sure that the queue will process only one job at a time.

In a local environment, where events have a very low chance of getting fired concurrently, it's probably ok to just use the `sync` driver.

Tweaking projector order
--------------------------------------------------------------------------------------------------------------------------------

You can add a getWeight method to a projector to tweak the order projectors are run in. Projectors with a lower weight run first. When no explicit weight is provided, the weight is considered `0`.

```
namespace App\Projectors;

use Spatie\EventSourcing\EventHandlers\Projectors\Projector;
use Spatie\EventSourcing\StoredEvents\StoredEvent;

class MyProjector extends Projector
{
    public function getWeight(?StoredEvent $event): int
    {
        return 5;
    }

    //
}
```

Alternatively, you can determine the weight dynamically based on the event being processed. This allows you to prioritize certain events over others. The `$event` parameter will be `null` when the `resetState()` method is called (during projector reset operations).

```
namespace App\Projectors;

use App\Events\MoneyAddedEvent;
use App\Events\MoneySubtractedEvent;
use Spatie\EventSourcing\EventHandlers\Projectors\Projector;
use Spatie\EventSourcing\StoredEvents\StoredEvent;

class MyProjector extends Projector
{
    public function getWeight(?StoredEvent $event): int
    {
        return match ($event?->event_class) {
            MoneyAddedEvent::class => 2,
            MoneySubtractedEvent::class => -2,
            default => 0,
        };
    }

    //
}
```

Note that providing a weight on a queued projector won't guarantee execution order.

Want to know more?
------------------------------------------------------------------------------------------------------------

We discuss projections and complex patterns such as CQRS in depth in our [Event Sourcing in Laravel](https://event-sourcing-laravel.com/) course. In practice, you want to check out these chapters:

- 5. Storing and Projecting Events
- 6. [Projectors in Depth](https://event-sourcing-laravel.com/projectors-in-depth)
- 14. CQRS
