Rails Spring Wisper Слушатель Метод Кэширование
Оказывается, Spring кеширует мой метод прослушивания wisper (я пишу довольно простой движок).
Пример:
приложение / модели / 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 stop
команда, которая действительно раздражает.
Что может быть более загадочным, я могу изменить another_method
вернуть значение в false, а затем тесты не пройдены, что нормально, но когда я изменяю after_something
метод тела, чтобы сказать return false
это не оказывает никакого влияния на тесты (например, тело after_something
как-то кешируется).
Это не проблема с высоким приоритетом, потому что это странное поведение можно увидеть только внутри тела метода слушателя и легко преодолеть, переместив всю логику в другой метод в классе. В любом случае это может сбить с толку (особенно в начале, когда я не знал точную проблему).
1 ответ
Проблема правильно вызвана тем, что когда вы подписываетесь на слушателя глобально, даже если его класс перезагружен, объект остается в памяти, указывая на класс, из которого он был изначально создан, даже если класс был перезагружен за это время.
Попробуйте это в 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
удалит всех подписчиков, поэтому, если у вас есть код, подобный приведенному выше, в более чем одном движке, только последний загруженный механизм будет подписан на своих слушателей.