event sourcing

One of the things I love about Java is its native, compiler-level support for annotations, a form of syntactic metadata which can be applied to source code but also retain at run-time to influence application behavior. I use them almost daily in my projects.

I do a fair amount of consulting and development on event sourced applications and these usually use Axon, a popular CQRS & event sourcing framework. Recently, Axon version 3 was released, supporting a number of annotations that can turn any POJO (Plain Old Java Object) into an event-sourced aggregate.

The annotations in Axon inspired me to experiment with adding support for similar annotations to prooph, a PHP framework which I occasionally reference in my PHP conference talks and consulting. This experiment is now available online as a PHP package, on GitHub: https://github.com/prooph/annotations. It works with the last versions of the core prooph components.

The package, like Axon, introduces a number of annotations which allow you to turn any regular PHP class into an event-sourced aggregate. Unfortunately, annotations are not natively supported in PHP. They are written inside documentation blocks and require an additional parser to get working (in the case of my package, Doctrine Annotations). The following example snippet shows how these annotations are applied:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

classTodoItem

{

/**

* @AggregateIdentifier

* @var string

*/

private$itemId;

/**

* TodoItem constructor.

* @CommandHandler

* @param PostTodo $command

*/

publicfunction__construct(PostTodo$command)

{

AggregateLifecycle::recordThat(newTodoPosted($command->getItemId()));

}

/**

* @EventHandler

* @param TodoPosted $event

*/

publicfunctiononTodoPosted(TodoPosted$event)

{

$this->itemId=$event->getItemId();

}

}

@CommandHandler helps to get rid of some of the boilerplate code usually associated with command handlers in prooph (see this example). @EventHandler turns any annotated function into an event listener.

In this post I want to talk a little about concurrency in the context of CQRS and event sourcing. Specifically, when a single aggregate is concurrently accessed by two commands (or command handlers, really). Read more →

Requirements and applications evolve and change, leading to refactoring. For example, user registration now requires a first and last name, what was once an error may no longer be considered one, etc. In an event sourced application, that poses a few problems. In this post I’ll discuss a few strategies and my views on event versioning.

In a recent project I used Axon Framework together with JGroups, to create a clustered, or distributed command bus.

In that project we had some concurrency issues. One of those issues was that two events were applied on a single aggregate with an identical sequence number. The JGroupsConnector in Axon uses a consistent hashing algorithm to route commands. This ensures that commands with the same routing key will be sent to the same member, regardless of the sending member of that message. Within the project we used the aggregate identifier as the routing key, ensuring that commands for a single aggregate are processed in a single JVM, thus preventing duplicate sequence numbers.

To demonstrate such a setup, I’ve created a simple demo application, based on the latest version of Axon Framework (3.0-M3). Using Docker Compose, the application is launched twice (in two containers). The containers should then form a JGroups cluster, and handle a number of commands. Go check it out on GitHub!