Created
March 22, 2016 11:11
-
-
Save eterps/9cf1245d347a8eba46ea to your computer and use it in GitHub Desktop.
Playing around with event sourcing principles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'yaml' | |
class Storage # Normally should be Redis or Kafka? | |
def self.events | |
@events ||= [] | |
end | |
end | |
# Aggregates (models) | |
class Order | |
attr_reader :items | |
def initialize(order_id) | |
@order_id = order_id | |
@items = [] | |
end | |
def order_total | |
@items.inject(0) do |sum, item| | |
sum + item.price | |
end | |
end | |
# Commands | |
def add_item(item_uid, price) | |
apply_event ItemAddedEvent.new(item_uid, price) | |
end | |
def remove_item(item_uid) | |
apply_event ItemRemovedEvent.new(item_uid) | |
end | |
# Applying events | |
def apply_event(event) | |
Storage.events << YAML.dump(event) # store event (should be Redis/Kafka) | |
# apply it | |
if event.is_a? ItemAddedEvent | |
@items << Item.new(event.item_uid, event.price) | |
# INSERT INTO # (immediate consistency) | |
elsif event.is_a? ItemRemovedEvent | |
@items.delete_if{|item| item.uid == event.item_uid} | |
# DELETE # (immediate consistency) | |
end | |
end | |
# Rebuilding | |
def rebuild | |
events = Storage.events.map{|event| YAML.load(event)} | |
events.each{|event| apply_event event} | |
end | |
end | |
class Item | |
attr_reader :uid, :price | |
def initialize(uid, price) | |
@uid = uid | |
@price = price | |
end | |
end | |
# Events | |
class ItemAddedEvent | |
attr_reader :item_uid, :price | |
def initialize(item_uid, price) | |
@item_uid = item_uid | |
@price = price | |
@time_added = Time.now | |
end | |
end | |
class ItemRemovedEvent | |
attr_reader :item_uid | |
def initialize(item_uid) | |
@item_uid = item_uid | |
end | |
end | |
# In Action | |
order = Order.new('0001') | |
order.add_item 'item_uid-1', 1.0 # should be +1.0 ? With de-duplication? | |
order.add_item 'item_uid-2', 2.0 | |
order.add_item 'item_uid-3', 3.0 | |
puts "Order total with 3 items: #{order.order_total}" | |
order.remove_item 'item_uid-2' | |
puts "Order total with 2 items: #{order.order_total}" | |
order = Order.new('0001') | |
order.rebuild | |
puts "Order total after rebuild: #{order.items.count} items, $#{order.order_total}" | |
# The write side and read side won't use the same data store, but can reside in the same database (but different tables) | |
# http://karmajunkie.com/event-sourcing-talk/#1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment