I want to register a global listener in my ApplicationController, that contains the current_user. I ended up trying this:
class ApplicationController < ActionController::Base
before_action do
@listener = MyListener.new(current_user)
Wisper.clear if Rails.env.development?
Wisper.subscribe(@listener, scope: :MyPublisher)
end
end
However, when I deployed this code to heroku these global listeners never get unsubscribed and the app keeps on accumulating listeners through requests. I can't rely on after_action since the application could terminate due to an error. What is the right way of doing this, is it to forcibly clear before I subscribe, like this?
class ApplicationController < ActionController::Base
before_action do
@listener = MyListener.new(current_user)
Wisper.clear
Wisper.subscribe(@listener, scope: :MyPublisher)
end
end
In another question, Kris suggested that we should use an initializer which subscribes once. The reason I am not doing this is because I want to have access to the current_user, and I prefer not to pass it via global variables/Thread.current. What is the best way to make GlobalListeners work with current_user?
My use case is to process all instances of ActiveRecord models loaded by current_user across all controller actions. Wisper does exactly what I needed it to do except for the issue mentioned.
class MyPublisher < ActiveRecord::Base
include Wisper::Publisher
after_find { broadcast(:process_find, self) }
end
and for the Listener:
class MyListener
def initialize(current_user)
@current_user = current_user
end
def process_find
...
end
end