0 18


[WIP] - PHPCon.pl 2015 workshop material

On Github Ocramius / real-time-applications-and-event-sourcing-in-php


I'm Marco!


Real-Time Event Sourcing

What is an event?

An event is a state transition

The only constant is change

What is a domain event?

A domain event is a state transition in your domain

Any state can be computed from previous state transitions

What is event sourcing?

event sourcing = saving state transitions

No saving state

state can be re-computed

state can be cached

Your object relational graph is cached state

Your DB is cached state

Your web pages are cached state

Machines are incredibly good at sequential reads

Events are in a sequence

Events are immutable

Cache forever

Reconstructing state is fast

Machines are incredibly good at sequential writes

Writes are also sequential

append-only event store

Less race conditions

No data loss, ever.

class ATraditionalCounter
    private $count = 0;

    public function increment()
        $this->count += 1;

    public function getCurrentCount() : int
        return $this->count;

There is absolutely nothing wrong with ATraditionalCounter

But what if we need any of the following?

  • ATraditionalCounter#getWhenTheCounterWasIncremented()
  • ATraditionalCounter#whoIncrementedTheCounter()
  • ATraditionalCounter#whenWasTheCounterCreated()
  • ATraditionalCounter#whenWasTheCounterLastUpdated()

All dumb questions when nobody cares...

... big trouble for accounting, invoicing, banking, geolocation, analytics.

class AnEventSourcedCounter
    private $events;

    public function increment()
        $this->events = new CounterWasIncremented(1, new \DateTime('now'), whoami());

    public function getCurrentCount() : int
        return count(array_filter(
            function ($event) {
                return $event instanceof CounterWasIncremented;

What will we build?

An event-sourced CQRS application


No frameworks

No magic

Just HTTP and PHP

AJAX Polling (for simplicity)

We need a domain that makes sense for this

There is no point in building event-sourced apps for CRUD

I chose Bowling for that.

The rules of bowling