Commit c19719a6 authored by Josianne Hyson's avatar Josianne Hyson

Add EE only version of EventStore configuration

We want to be able to subscribe to events with workers that are only
declared in the EE version of GitLab. Add an EE version of the
EventStore class that we can declare these subscribers in. Also ensure
that the publish event doesn't raise an error when there are not
subscribers for that event. This stops the CE code from raising an error
when a subscriber is only declared in EE.

Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/351423
MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79291
parent 2c753f80
......@@ -252,19 +252,20 @@ add a line like this to the `Gitlab::EventStore.configure!` method:
```ruby
module Gitlab
module EventStore
def self.configure!
Store.new.tap do |store|
# ...
def self.configure!(store)
# ...
store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
# ...
end
# ...
end
end
end
```
A worker that is only defined in the EE codebase can subscribe to an event in the same way by
declaring the subscription in `ee/lib/ee/gitlab/event_store.rb`.
Subscriptions are stored in memory when the Rails app is loaded and they are immediately frozen.
It's not possible to modify subscriptions at runtime.
......
# frozen_string_literal: true
module EE
module Gitlab
module EventStore
extend ActiveSupport::Concern
class_methods do
extend ::Gitlab::Utils::Override
# Define event subscriptions using:
#
# store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent)
#
# It is possible to subscribe to a subset of events matching a condition:
#
# store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent), if: ->(event) { event.data == :some_value }
#
# Only EE subscriptions should be declared in this module.
override :configure!
def configure!(store)
super(store)
###
# Add EE only subscriptions here:
end
end
end
end
end
......@@ -18,7 +18,7 @@ module Gitlab
end
def self.instance
@instance ||= configure!
@instance ||= Store.new { |store| configure!(store) }
end
# Define all event subscriptions using:
......@@ -29,14 +29,14 @@ module Gitlab
#
# store.subscribe(DomainA::SomeWorker, to: DomainB::SomeEvent), if: ->(event) { event.data == :some_value }
#
def self.configure!
Store.new do |store|
###
# Add subscriptions here:
def self.configure!(store)
###
# Add subscriptions here:
store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
end
store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
end
private_class_method :configure!
end
end
Gitlab::EventStore.prepend_mod_with('Gitlab::EventStore')
......@@ -29,7 +29,7 @@ module Gitlab
raise InvalidEvent, "Event being published is not an instance of Gitlab::EventStore::Event: got #{event.inspect}"
end
subscriptions[event.class].each do |subscription|
subscriptions.fetch(event.class, []).each do |subscription|
subscription.consume_event(event)
end
end
......
......@@ -224,6 +224,26 @@ RSpec.describe Gitlab::EventStore::Store do
store.publish(event)
end
end
context 'when the event does not have any subscribers' do
let(:store) do
described_class.new do |s|
s.subscribe unrelated_worker, to: another_event_klass
end
end
let(:event) { event_klass.new(data: data) }
it 'returns successfully' do
expect { store.publish(event) }.not_to raise_error
end
it 'does not dispatch the event to another subscription' do
expect(unrelated_worker).not_to receive(:perform_async)
store.publish(event)
end
end
end
describe 'subscriber' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment