Event sourcing

 

@JakubPilimon

jakub.pilimon@gmail.com

github.com/pilloPl

ORM

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

  @StreamListener("items")
  public void itemEventStream(ItemPaid itemPaid) {
        log.info("Received item paid event {}", itemPaid);
        readModel.markItemAsPaid(itemPaid.getUuid(), 
                                 itemPaid.getWhen());
  }
   @Publisher(channel = "items")
   public ItemPaid ship(ItemPaid itemPaid) {
        log.info("sending:  {}", itemPaid);
        return itemPaid;
   }
spring.cloud.stream.bindings.items.destination=items

Horizontal asymmetric scaling

spring.cloud.stream.bindings.items.destination=items
spring.cloud.stream.bindings.items.group=ui

spring.cloud.stream.bindings.items.destination=items
spring.cloud.stream.bindings.items.group=ui_2nd_instance


Failover

spring.cloud.stream.bindings.items.destination=items
spring.cloud.stream.bindings.items.group=ui

spring.cloud.stream.bindings.items.destination=items
spring.cloud.stream.bindings.items.group=ui

A/B testing

&

blue green deployments

Partitioning

spring.cloud.stream.bindings.items.destination=items
spring.cloud.stream.bindings.items.group=ui

spring.cloud.stream.instanceIndex=1
spring.cloud.stream.instanceCount=2

Performance

Shop

(write model)

UI (read model)

eventually events

commands

DTOs

front end

Pitfalls

Thank you!

@JakubPilimon

jakub.pilimon@gmail.com

github.com/pilloPl

Event Sourcing/CQRS 4developers

By Jakub Pilo

Event Sourcing/CQRS 4developers

Overview of event sourcing and CQRS benefits

  • 2,126