PHPackages                             simgroep/event-sourcing - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. simgroep/event-sourcing

AbandonedLibrary

simgroep/event-sourcing
=======================

0.1.0(10y ago)88323PHPPHP &gt;=5.6.0

Since Apr 13Pushed 8y ago14 watchersCompare

[ Source](https://github.com/simgroep/event-sourcing)[ Packagist](https://packagist.org/packages/simgroep/event-sourcing)[ RSS](/packages/simgroep-event-sourcing/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (9)Versions (10)Used By (0)

simgroep/event-sourcing
=======================

[](#simgroepevent-sourcing)

Provides several components on top of [broadway](https://github.com/qandidate-labs/broadway).

Concurrency
-----------

[](#concurrency)

Updating an aggregate root at the same time may lead to concurrency problems. To solve this we provide a *CommandGateway* and a *LockingRepository*, inspired by the [Axon Framework](https://github.com/AxonFramework/AxonFramework).

The *LockingRepository* will prevent access to the repository once load() is called. When save() is called, the lock will be released. Trying to access the repository while being locked will result in a *ConcurrencyException*.

The *CommandGateway* will in turn catch the *ConcurrencyException*, and will try do dispatch the command again until a specific condition is met (depends on the used *Scheduler* implementation), or throw the *ConcurrencyException* otherwise.

Replaying Events
----------------

[](#replaying-events)

The EventSourcingBundle contains commands to make interactive replaying of events available after doing a few simple steps.

#### Mark projectors for replaying

[](#mark-projectors-for-replaying)

The bundle needs to be aware which projectors are replayable and what there corresponding repositories are.

Projectors are tagged by 'projector.replayable' and the 'repository attribute' is used to define the repository.

For example:

```
sim.read_model.projector.municipality_hostname:
        class: SIM\Settings\ReadModel\MunicipalityHostnameProjector
        arguments: [@sim.read_model.repository.municipality_hostname]
        tags:
            - { name: broadway.domain.event_listener }
            - { name: projector.replayable, repository: sim.read_model.repository.municipality_hostname}
```

#### Test if your projectors are correctly tagged as replayable

[](#test-if-your-projectors-are-correctly-tagged-as-replayable)

After tagging your projectors you can test the outcome with the next command: (don't forget to clear the symfony cache.)

```
vagrant@dev:/var/www/someproject-api$ php ./app/console  simgroep:eventsourcing:projectors:list

The following projectors are available for rebuilding:
- sim.read_model.repository.municipality_hostname
```

You can directly see if your projectors are marked for rebuilding their projections.

#### Replay time

[](#replay-time)

Now it's time for the fun part ...replaying!. There are three forms of replaying:

- non-interactive replaying (multi threaded)
- replay a specific stream of events
- interactive replaying

###### Non-interactive replaying

[](#non-interactive-replaying)

Non-interactive replaying is straight forward.

```
php ./app/console simgroep:eventsourcing:events:replay --threads 4 all
```

- You can define a specific projector (ex: php ./app/console simgroep:eventsourcing:events:replay municipality\_hostname).
- You can define multiple projectors (ex: php ./app/console simgroep:eventsourcing:events:replay 'projector1,projector2').
- A third option is to define all projectors (ex: php ./app/console simgroep:eventsourcing:events:replay all).

With "--threads" you can define the number of threads. The maximum number of threads is the number of cpu cores \* 2.

Note: "--threads" cannot be used with interactive mode or when replaying a specific stream

###### Replay a specific stream of events

[](#replay-a-specific-stream-of-events)

If you want to replay only the events from a specific stream then

```
php ./app/console simgroep:eventsourcing:events:replay --stream 00000000-0000-0000-0000-000000000000 all
```

###### Interactive replaying

[](#interactive-replaying)

When time travelling becomes important for debugging purposes then you can choose for interactive replaying of your event store.

Interactive replaying contains one extra argument (--interact) and a value which contains the stream id.

```
php ./app/console simgroep:eventsourcing:events:replay --interact 00000000-0000-0000-0000-000000000000 all
```

Every event of the event store will be replayed, if one those events contains the supplied stream id and hits one of the selected projectors then:

1. The event will be replayed first and the first projection will be updated.
2. The replaying will pause if gives you the option to continue or stop replaying.
3. If multiple projectors are affected by this event then the next projector will be updated and we will go back to step 2.

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 51.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~97 days

Total

2

Last Release

3798d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/1297db74356a6aa881ad109d47a50987e5825a75e7399098d6f86792027a5fbc?d=identicon)[simgroep](/maintainers/simgroep)

![](https://www.gravatar.com/avatar/ba522e901313f2437eb205ef9863f5b7e54cb97c847d8fe8ca7f3d05b75a116d?d=identicon)[JurJean](/maintainers/JurJean)

---

Top Contributors

[![weemen](https://avatars.githubusercontent.com/u/4239392?v=4)](https://github.com/weemen "weemen (20 commits)")[![JurJean](https://avatars.githubusercontent.com/u/409761?v=4)](https://github.com/JurJean "JurJean (12 commits)")[![bartdezwaan](https://avatars.githubusercontent.com/u/1033876?v=4)](https://github.com/bartdezwaan "bartdezwaan (7 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/simgroep-event-sourcing/health.svg)

```
[![Health](https://phpackages.com/badges/simgroep-event-sourcing/health.svg)](https://phpackages.com/packages/simgroep-event-sourcing)
```

###  Alternatives

[team-reflex/discord-php

An unofficial API to interact with the voice and text service Discord.

1.1k379.4k24](/packages/team-reflex-discord-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
