Rails singleton became empty after development reload

醉酒当歌 提交于 2021-02-20 18:45:42

问题


In my rails app I've decided to use singleton to create some sort of factory to get objects properly.

config/initializers/registry.rb:

registry = Registry.instance

registry.define_lazy :period_predictor do
  PeriodPredictor.new(NotificationBuilder.new, 28, 4, 3)
end

registry.define_lazy :notification_sender do
  NotificationSender.new
end

lib/registry.rb:

# Registry class which is singleton and stores values.
class Registry
  include Singleton


  # Define simple value. Like a constant.
  #
  # @param key [Symbol]
  # @param value
  def define(key, value)
    container[key] = value
  end


  # Define value (block required) which will be calculated when it will be need.
  # It will calculate it every time when it will be needed.
  #
  # @param key [Symbol]
  # @param block [Proc]
  def define_lazy(key, &block)
    container[key] = LazyValue.new(&block)
  end


  # Get value.
  #
  # @param key [Symbol]
  #
  # @return
  def get(key)
    value = container[key]
    if value.is_a?(LazyValue)
      value = value.call
    end

    value
  end


  # Get value (hash access).
  #
  # @param key [Symbol]
  #
  # @return
  def [](key)
    get(key)
  end


  # Export all the values.
  # Replacing values of returned hash won't change registry.
  #
  # @return [Hash]
  def export
    container.clone
  end


  # Import hash data to registry
  #
  # @param data [Hash]
  def import(data)
    data.each do |key, value|
      @container[key] = value
    end
  end


  private

  # Get container.
  #
  # @return [Hash]
  def container
    @container ||= {}
  end


  # Class to store lazy value.
  class LazyValue
    def initialize(&block)
      @block = block
    end

    def call
      @block.call
    end
  end
end

Everything works fine in production. But when I change something (even add space somewhere), I can't get data from singleton anymore in controllers.

Registry.instance became just fresh instance of registry and Registry.instance[:period_predictor] became nil

Same thing happens when I just go away with singleton and make class methods.

It does not do this thing only if I turn off singleton and create a constant:

registry = Registry.new

registry.define_lazy :period_predictor do
  PeriodPredictor.new(NotificationBuilder.new, 28, 4, 3)
end

registry.define_lazy :notification_sender do
  NotificationSender.new
end

REGISTRY = registry

Rails version 4.2.5.1

Do someone have any ideas why this is happening?


回答1:


I've figured out, that it happenes because Rails refreshes autoloaded constants. http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#constant-reloading

I've added line require "#{Rails.root}/lib/registry" at the beggining of initializer and everything is OK.



来源:https://stackoverflow.com/questions/39498241/rails-singleton-became-empty-after-development-reload

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!