Event sourcing

 

@JakubPilimon

jakub.pilimon@gmail.com

github.com/pilloPl

ORM

STATE

STATE

new ShopItem("ordered")
item.setStatus("paid")
...
insert into shop_items (id, status) values (1, 'ordered')
update shop_items set status = 'paid' where id = 1
...
"new instance of ordered Shop Item was created"
"this shop item was marked as paid"
...
new ItemOrdered(itemID, timestamp)
new ItemPaid(itemID, timestamp)
item.setStatus("paid")
new ShopItem("ordered")
new ShopItem("ordered")
ordered.setStatus("paid")

State 1

State 2 

(State 1 + Event 2)

single ShopItem deltas

technology agnostic log, descriptive event log

@Entity
class Product {

    private float price;
    
    //...
    
    public void cutPrice(int percent) {    
        checkState(percent < 100);
        this.price = 
                price - price * percent / 100;
        DomainEvents.publish(
                new NewPriceAssigned(percent, this.id));
    
    }

}
 def 'should cut price by 10 percent'() {
        given:
            ShopItem item = newWithPrice(50.00)
        when:
            item.cutPrice(10)
        then:
            item.price == 45.00
    }
 def 'should cut price by procent'() {
        given:
            ShopItem item = newWithPrice(50)
        when:
            item.cutPrice(10)
        then:
            item.getUncommittedChanges() ==
                        [new NewPriceAssigned(price: 45)]
    }

QUERIES

message broker

Shop

UI

Horizontal asymmetric scaling

Failover

A/B testing

&

blue green deployments

Partitioning

Adding new service

message broker

Shop

UI

Orders

Manager

Shipping

Performance

Testing?

Shop

(write model)

UI (read model)

eventually events

commands

DTOs

front end

Pitfalls

Replaying with side effect

calling SMS service

Event handler

IDEMPOTENCY

Replaying with side effect

SmsRequested

Event handler

calling SMS service

deleting SmsRequested

no 2PC

Process  manager

new SmsRequested(uuid)

Event handler

calling SMS service

new SmsSent(uuid)

event store

@StreamListener(Sink.INPUT)
public void commandStream(Event event) {
    //...saveSomething and changeState
}

//not run when replying!!!
@AfterAcknowledging(Sink.INPUT)
public Consumer<Event> doNext(Event event) {
    return event -> ...
}

Thank you!

@JakubPilimon

jakub.pilimon@gmail.com

github.com/pilloPl

Event sourcing

By Jakub Pilo

Event sourcing

Overview of event sourcing and CQRS benefits

  • 831