Skip to content

Instantly share code, notes, and snippets.

@hallgren
Forked from jesjos/proposal.rb
Last active August 29, 2015 14:13
Show Gist options
  • Save hallgren/f7df85d836cdf3a4f580 to your computer and use it in GitHub Desktop.
Save hallgren/f7df85d836cdf3a4f580 to your computer and use it in GitHub Desktop.
# = Example Sandthorn setup
Sandthorn.config do |sand|
snapshot_store = SnapshotStore.new
sand.event_stores = {
default: EventStore.new(event_driver: SequelDriver.new(url: "sqlite://my_db"), snapshot_driver: snapshot_store)
mongo: EventStore.new(event_driver: MongoDBDriver.new(), snapshot_driver: snapshot_store)
alternative: ObjectStore.new(object_driver: InMemoryDriver.new)
aux: InMemoryStore.new
}
# This maps aggregates to event stores.
# Aggregates that aren't exlicitly mapped will be stored in the default store.
# I see the need to be able to define either concrete classes or patterns.
sand.aggregate_mappings = {
alternative: [StoreAggregates::Foo, StoreAggregates::Bar]
aux: /LogAggregates/
}
end
# Example aggregate
class MyAggregate
include EventStore::AggregateRoot
attr_reader :name
def initialize(name: nil)
@name = name
end
def change_name(name)
@name = name
name_changed
end
def name_changed
commit
end
end
# = Committing
# When commit is called, we just construct the appropriate event and save it in the aggregate.
# The events should be in the agreed-upon event format.
# = Saving an aggregate
# Saving means finding the appropriate event store for the aggregate type, and then calling `save_events` on the event store with any unsaved events.
# Example:
# 1. my_aggregate.save calls Sandthorn.event_store_for(my_aggregate) and gets an event_store
# 2. Call event_store.save_events(my_aggregate, my_aggregate.unsaved_events)
# Here's an incomplete implementation of AggregateRoot
module EventStore
module AggregateRoot
attr_reader :unsaved_events
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def event_store
Sandthorn.event_store_for(self)
end
end
def save
if unsaved_events.any?
save_events(unsaved_events)
end
end
private
def save_events(events)
event_store.save_events(self, events)
end
def event_store
self.class.event_store
end
end
end
@hallgren
Copy link
Author

Yes you can be right about taking Sandthorn in the wrong direction and make the scope to big.

It maybe easier to just use Active Record directly for the objects that not have to be backed by events. I have encountered cases there event based object are overkill and a classic state based object could be enough and that it could be queried by default. Events are only an implementation detail that builds the objects.

  • Yes a ruby object lives in memory but a http request is stateless and to be able to access a object in a second request it has to be stored somewhere that be memory or on disk. The InMemory store are persisted as long as its host. In the end of the day it probably used most for testing the domain.
  • I think we mean the same thing.
  • The EventStore should have the same API objects out and event in. Then its up to the driver or that we call it to store the events as it please. An EventStore stores events in a pre defined format. Then the projections is coupled to the EventStore independent of underlying sequel or mongo db.

In the end we want the same thing I maybe take it a step to far.

@hallgren
Copy link
Author

I had some nightly insight around this discussion.

We plan to inject Buckthorn in Sandthorn but the API towards Buckthorn are objects, if I remember it correctly. Sandthorn will not know how the Buckthorn objects are stored. (events or only state). Would´t be a smell if the AggregateRoot are in Sandthorn but the objects from Buckthorn would not include it? As the objects from Buckthorn are modeled in Elixir/Erlang code and not in ruby land.

@jesjos
Copy link

jesjos commented Jan 21, 2015

I wrote a super long comment and then accidentally clicked the back-button.

@hallgren
Copy link
Author

Noooo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment