Skip to content

Commit 2d89810

Browse files
committed
Prevent processing events when different version is activating
During activation the last existing events are replayed before the projector is marked active. Block new events since they will not be picked up by the replay process.
1 parent 00442e6 commit 2d89810

3 files changed

Lines changed: 18 additions & 9 deletions

File tree

lib/sequent/core/event_publisher.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module Core
55
class ProjectorMigrationError < RuntimeError; end
66
class UnknownActiveProjectorError < ProjectorMigrationError; end
77
class ReplayingProjectorMismatchError < ProjectorMigrationError; end
8-
class NewerProjectorIsActiveError < ProjectorMigrationError; end
8+
class DifferentProjectorVersionIsActiveError < ProjectorMigrationError; end
99

1010
#
1111
# EventPublisher ensures that, for every thread, events will be published

lib/sequent/core/projector.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,19 @@ def is_active?
206206
projector_state = Projectors.projector_states[self.class.name]
207207
return false if projector_state.nil?
208208

209-
return true if projector_state.active_version == version
210-
211-
# Replaying or activating the current version, so run this projector (it will write to a temporary table).
212-
return true if projector_state.replaying_version == version || projector_state.activating_version == version
209+
if projector_state.activating_version.present?
210+
# Current projector version is activating, so we write to the temporary replay table.
211+
return true if projector_state.activating_version == version
212+
else
213+
return true if projector_state.active_version == version
214+
215+
# Replaying the current version, so run this projector (it will write to a temporary table).
216+
return true if projector_state.replaying_version == version
217+
end
213218

214-
fail NewerProjectorIsActiveError,
219+
# A different projector version is active or activating, so we cannot write new events since they will
220+
# not be properly propagated.
221+
fail DifferentProjectorVersionIsActiveError,
215222
"projector #{self.class} version #{version} does not match state #{projector_state}"
216223
end
217224
end

spec/lib/sequent/core/event_publisher_spec.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,22 +84,24 @@ class UnknownProjector < Sequent::Core::Projector
8484
Sequent.configuration.event_handlers << TestEventHandler.new
8585
Sequent.configuration.command_handlers << TestCommandHandler.new
8686
Sequent.configuration.migrations_class = SpecMigrations
87+
Sequent.configuration.migrations_class.version = 0
88+
Sequent.activate_current_configuration!
8789
end
8890

8991
it 'fails when unknown projectors are active' do
90-
Sequent::Core::Projectors.register_active_projectors!([TestEventHandler, UnknownProjector], 1)
92+
Sequent::Core::Projectors.register_active_projectors!([TestEventHandler, UnknownProjector], 0)
9193

9294
expect do
9395
Sequent.command_service.execute_commands TriggerTestCase.new(aggregate_id: Sequent.new_uuid)
9496
end.to raise_error Sequent::Core::UnknownActiveProjectorError
9597
end
9698

97-
it 'fails when newer version of the projector is activating' do
99+
it 'fails when different version of the projector is activating' do
98100
Sequent::Core::Projectors.register_activating_projectors!([TestEventHandler], Sequent.new_version + 1)
99101

100102
expect do
101103
Sequent.command_service.execute_commands TriggerTestCase.new(aggregate_id: Sequent.new_uuid)
102-
end.to raise_error Sequent::Core::NewerProjectorIsActiveError
104+
end.to raise_error Sequent::Core::DifferentProjectorVersionIsActiveError
103105
end
104106
end
105107
end

0 commit comments

Comments
 (0)