Rails spring wisper listener方法缓存

时间:2016-04-27 19:34:10

标签: ruby-on-rails rails-spring wisper

事实证明,Spring缓存了我非常简单的监听器方法(我写的是非常简单的引擎)。

示例:

应用/模型/ myengine / my_class.rb

class Myengine::MyClass
  include Wisper::Publisher

  def something
    # some logic
    publish(:after_something, self)
  end
end

配置/初始化/ wisper.rb

Wisper.subscribe(Myengine::MyObserver.new)

应用/观察员/ myengine / my_observer.rb

class Myengine::MyObserver
  def after_something my_class_instance
    # any changes here requires Spring manual restart in order to be reflected in tests
    another_method
  end

  def another_method
    # all changes here or in any other class methods works ok with Spring and are instantly visible in tests
    return true
  end
end

通过Spring重启我的意思是手动执行spring stop命令,这真的很烦人。

更神秘的是,我可能会将another_method返回值更改为false,然后测试失败,这是正常的,但当我更改after_something方法正文时,请说return false它没有&# 39; t对测试有任何影响(比如after_something的主体以某种方式缓存)。

这不是高优先级问题,因为这种奇怪的行为只在侦听器方法体内可见,并且通过将所有逻辑移动到类中的另一个方法很容易克服。无论如何,它可能会让人感到困惑(特别是在开始的时候,我并不知道确切的问题)。

1 个答案:

答案 0 :(得分:3)

问题是正确引起的,因为当您全局订阅一个侦听器时,即使重新加载了它的类,该对象仍保留在内存中,指向它最初构造的类,即使该类已在此期间重新加载。 / p>

config/initializers/wisper.rb

中试试
Rails.application.config.to_prepare do
  Wisper.clear if Rails.env.development?
  Wisper.subscribe(Myengine::MyObserver.new)
end

to_prepare将在每次开发环境请求之前运行块,但是一次,正常情况下生产环境。因此,如果您的监听器没有维持任何状态,它应该按预期工作。

在我们从重新加载的类重新订阅新实例之前,需要Wisper.clear来删除已订阅的现有侦听器。请注意#clear将清除所有订阅者,因此如果您在多个引擎中具有与上述类似的代码,则只有最后一个要加载的引擎才会订阅其侦听器。