Open
Description
Probably the code will tell it clearier than I can explain ;)
In short - we're having two aggregates. There's a circular dependency between them (via events).
Once we started caching (here simulated with $global_var) the first aggregate we noticed a WrongExpectedEventVersion
exception.
The fix was to set the version
and unpublished_events
manually.
class AggregateRootBugTest < ActiveSupport::TestCase
def test_versioning_broken
event_store = RailsEventStore::Client.new(
repository: RubyEventStore::InMemoryRepository.new,
)
$aggregate_1 = Aggregate_1.new
$aggregate_1.load("stream_1", event_store: event_store)
event_store.subscribe(
-> _ {
aggregate = Aggregate_2.new
aggregate.load("stream_2", event_store: event_store)
aggregate.publish_event_2
aggregate.store("stream_2", event_store: event_store)
},
to: [Event_1]
)
event_store.subscribe(
-> _ {
# uncommenting the code should fix the bug (and fail the test)
# $aggregate_1.instance_variable_set(:@version, ($aggregate_1.instance_variable_get(:@version) || -1) + $aggregate_1.unpublished_events.size)
# $aggregate_1.instance_variable_set(:@unpublished_events, [])
$aggregate_1.do_something_in_reaction_to_event_2
assert_raise(RubyEventStore::WrongExpectedEventVersion, bug_fixed_message) do
$aggregate_1.store("stream_1", event_store: event_store)
end
},
to: [Event_2]
)
$aggregate_1.publish_event_1
$aggregate_1.store("stream_1", event_store: event_store)
end
def bug_fixed_message
"If this test fails, it means that AggregateRoot has the bug fixed. "+
"Go and remove the hack in Foo::Bar (global cache) " +
"It has something to do with setting ivars for version and events"
end
class Aggregate_1
include AggregateRoot
def publish_event_1
apply(Event_1.new(data: {}))
end
def do_something_in_reaction_to_event_2
end
def apply_event_1(event)
end
end
class Aggregate_2
include AggregateRoot
def publish_event_2
apply(Event_2.new(data: {}))
end
def apply_event_2(event)
end
end
class Event_1 < RailsEventStore::Event
end
class Event_2 < RailsEventStore::Event
end
end