【问题标题】:Wisper: unsubscribing GlobalListeners between requestsWisper:在请求之间取消订阅 GlobalListeners
【发布时间】:2016-05-11 08:04:23
【问题描述】:

我想在我的 ApplicationController 中注册一个全局监听器,它包含 current_user。我最终尝试了这个:

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

但是,当我将此代码部署到 heroku 时,这些全局侦听器永远不会取消订阅,并且应用程序会继续通过请求累积侦听器。 我不能依赖 after_action,因为应用程序可能会因错误而终止。这样做的正确方法是什么,在我订阅之前强制清除,就像这样?

class ApplicationController < ActionController::Base
  before_action do
    @listener = MyListener.new(current_user)
    Wisper.clear
    Wisper.subscribe(@listener, scope: :MyPublisher)
  end
end

在另一个question 中,Kris 建议我们应该使用一个订阅一次的初始化程序。我不这样做的原因是因为我想访问 current_user,并且我不想通过全局变量/Thread.current 传递它。让 GlobalListeners 与 current_user 一起工作的最佳方法是什么?

我的用例是处理 所有 个由 current_user 跨 所有 控制器操作加载的 ActiveRecord 模型实例。除了提到的问题之外,Wisper 完全做了我需要它做的事情。

class MyPublisher < ActiveRecord::Base
  include Wisper::Publisher
  after_find { broadcast(:process_find, self) }
end

对于监听器:

class MyListener
  def initialize(current_user)
    @current_user = current_user
  end

  def process_find
    ...
  end
end

【问题讨论】:

  • Wisper.clear 仅用于测试环境。它将清除所有全球订阅者。我怀疑它不能在 Heroku 上运行的原因是该应用程序正在生产环境中运行。
  • 全局侦听器不适用于您希望订阅仅在请求期间持续的情况。一种选择是临时全局监听器,它们是线程安全的,所以应该可以工作。但更好的是订阅控制器操作内的发布者实例。如果您显示您的发布商代码,我可以提供更好的帮助。
  • 感谢克里斯的快速响应。我已经更新了上面的问题,重申我的用例是订阅所有控制器操作中 ActiveRecord 模型的所有查找。你会推荐一个在 ApplicationController 中带有 around_action 块的 TemporaryGlobalListener 吗?
  • 我目前看不到任何方法来做你想做的事,因为你想订阅一个用本地数据(current_user)初始化的监听器到一个从全局发布的事件(MyPublisher 班级)。

标签: ruby-on-rails wisper


【解决方案1】:

你可以订阅你的听众globally for the duration of a block:

def show
  Wisper.subscribe(MyListener.new(current_user)) do
    @model = MyPublisher.find(id)
  end
end

当块完成时,监听器将被取消订阅。

如果您希望它发生在多个操作中,您可以使用around_action 过滤器:

around_action :subscribe_listener

def show
  @model = MyPublisher.find(id)
end

def create
  # ...
end

# etc.

private

def subscribe_listener
  Wisper.subscribe(MyListener.new(current_user)) do
    yield
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    相关资源
    最近更新 更多