New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change internal mapping for event subscriber registrations #3758
Changes from all commits
12520bb
c4af8bf
5d81ecc
d42cab1
026af1b
754346e
63aeaef
b2a5a03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# frozen_string_literal: true | ||
|
||
module Spree | ||
module Event | ||
class SubscriberRegistry | ||
def initialize | ||
@registry = {} | ||
@semaphore = Mutex.new | ||
end | ||
|
||
def register(subscriber) | ||
registry[subscriber.name] ||= {} | ||
end | ||
|
||
def activate_autoloadable_subscribers | ||
require_subscriber_files | ||
activate_all_subscribers | ||
end | ||
|
||
def activate_all_subscribers | ||
registry.each_key { |subscriber_name| activate_subscriber(subscriber_name.constantize) } | ||
end | ||
|
||
def deactivate_all_subscribers | ||
registry.each_key { |subscriber_name| deactivate_subscriber(subscriber_name.constantize) } | ||
end | ||
|
||
def activate_subscriber(subscriber) | ||
return unless registry[subscriber.name] | ||
|
||
subscriber.event_actions.each do |event_action, event_name| | ||
@semaphore.synchronize do | ||
unsafe_deactivate_subscriber(subscriber, event_action) | ||
|
||
subscription = Spree::Event.subscribe(event_name) { |event| subscriber.send(event_action, event) } | ||
|
||
# deprecated mappings, to be removed when Solidus 2.10 is not supported anymore: | ||
subscriber.send("#{event_action}_handler=", subscription) | ||
|
||
registry[subscriber.name][event_action] = subscription | ||
end | ||
end | ||
end | ||
|
||
def deactivate_subscriber(subscriber, event_action_name = nil) | ||
@semaphore.synchronize do | ||
unsafe_deactivate_subscriber(subscriber, event_action_name) | ||
end | ||
end | ||
|
||
private | ||
|
||
attr_reader :registry | ||
|
||
# Loads all Solidus' core and application's event subscribers files. | ||
# The latter are loaded automatically only when the preference | ||
# Spree::Config.events.autoload_subscribers is set to a truthy value. | ||
# | ||
# Files must be placed under the directory `app/subscribers` and their | ||
# name must end with `_subscriber.rb`. | ||
# | ||
# Loading the files has the side effect of adding their module to the | ||
# list in Spree::Event.subscribers. | ||
def require_subscriber_files | ||
pattern = "app/subscribers/**/*_subscriber.rb" | ||
|
||
# Load Solidus subscribers | ||
# rubocop:disable Rails/DynamicFindBy | ||
solidus_core_dir = Gem::Specification.find_by_name('solidus_core').gem_dir | ||
# rubocop:enable Rails/DynamicFindBy | ||
Dir.glob(File.join(solidus_core_dir, pattern)) { |c| require_dependency(c.to_s) } | ||
|
||
# Load application subscribers, only when the flag is set to true: | ||
if Spree::Config.events.autoload_subscribers | ||
Rails.root.glob(pattern) { |c| require_dependency(c.to_s) } | ||
end | ||
end | ||
|
||
def unsafe_deactivate_subscriber(subscriber, event_action_name = nil) | ||
to_unsubscribe = Array.wrap(event_action_name || subscriber.event_actions.keys) | ||
|
||
to_unsubscribe.each do |event_action| | ||
if (subscription = registry.dig(subscriber.name, event_action)) | ||
Spree::Event.unsubscribe(subscription) | ||
|
||
registry[subscriber.name].delete(event_action) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,9 @@ module Preferences | |
# | ||
# @deprecated | ||
def reset_spree_preferences(&config_block) | ||
Spree::Config.instance_variables.each { |iv| Spree::Config.remove_instance_variable(iv) } | ||
Spree::Config.instance_variables. | ||
reject { |iv| iv == :@events_configuration }. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure about this. What if some specs need to reset that configuration? It's applicable? How do people know that all the preferences except that one will be reset when calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This helper method is deprecated, so it won't be around for long. We don't use it anymore in our codebase, but we have some specs that verify its behavior. I'm not sure if creating a better workaround for making it work properly with the new event mappings is worth the effort at this point. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh right, it's deprecated. 👍 |
||
each { |iv| Spree::Config.remove_instance_variable(iv) } | ||
Spree::Config.preference_store = Spree::Config.default_preferences | ||
|
||
if defined?(Railties) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we need to deprecate the writer as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still use the writer internally to keep compatibility, if somebody is still using the reader in their codebase (we don't use the reader anymore). So, if we deprecate the writer, then we'll need to silence the deprecation when using it. So, deprecating the writer would be impractical at this point.
But I think we don't really need to deprecate the writer as well. The only reason for some developers to be using the writer in their codebase is to set a value to be accessed from the reader. When this happens, they will see the deprecation when the matching reader is called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, thanks Andrea.