We are happy to announce the release of our php
library patchlevel/event-sourcing in
version 3.7.0. This release contains a small feature
for the InMemorySubscriptionStore
, a performance optimization for the subscriptions and a bigger new feature which
enable to create small or micro aggregates. So let's get started.
InMemorySubscriptionStore
Next, is a small DX feature regarding testing. The InMemorySubscriptionStore
has now a new method clear
to reset the
internal subscription state. This means that after calling InMemorySubscriptionStore::clear
all information on the
subscriptions like position and state are removed.
Subscriptions: New Failed Status
Subscriptions can now have a new status called failed
. This indicates, that a subscription could not overcome the
error
state with the retry strategy chosen. This happens for example when the max retries where reached. Subscriptions
with status failed
are ignored by the subscription engine, which leads to better performance since the subscription
engine can now load less events based of the position of the remaining subscriptions.
This new status is technically a BC-Break as we added a new case in our Status
enum. We decided to ship this
nevertheless in a minor version since it should be really rare that this enum was used by our users. On the other hand
this results in a better performance and therefore a better experience when using the subscription system.
If you want to know about
the subscription statuses you should
read our docs for the subscriptions.
New Stream Attribute to enable Micro Aggregates
Now to the biggest change in this version, a new attribute called #[Stream]
. With this we can, when using the
StreamStore
, configure in which stream the events should be saved and loaded from. Previously, the stream was
structured based on the aggregate as follows: {aggregateName}-{aggregateId}
. Now, using the new attribute you can
decide freely which stream should be used. Also {id}
is a placeholder that can be used for the aggregate ID when
defining the stream.
use Patchlevel\EventSourcing\Aggregate\BasicAggregateRoot;
use Patchlevel\EventSourcing\Attribute\Aggregate;
use Patchlevel\EventSourcing\Attribute\Stream;
#[Aggregate('profile')]
#[Stream('profile-{id}')]
final class Profile extends BasicAggregateRoot
{
}
You can also use the same stream as another aggregate. This would cause both aggregates to read and write to the same
stream. The ability to specify the stream of another aggregate is added of better DX by providing the FQCN of the
aggregate.
use Patchlevel\EventSourcing\Aggregate\BasicAggregateRoot;
use Patchlevel\EventSourcing\Attribute\Aggregate;
#[Aggregate('meeting')]
final class Meeting extends BasicAggregateRoot
{
}
use Patchlevel\EventSourcing\Aggregate\BasicAggregateRoot;
use Patchlevel\EventSourcing\Attribute\Aggregate;
#[Aggregate('guest_list')]
#[Stream(Meeting::class)]
final class GuestList extends BasicAggregateRoot
{
}
This feature is a step directed to smaller or even Micro Aggregates and for Dynamic Consistency Boundaries. This feature
comes from input we got after giving talks at
a symfony user group at cologne. For more information about
this topic you can have a look at
our docs and
this GitHub issue where we listed some resources. We are also
planning a dedicated blog post about this topic, so stay tuned!