Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails singleton became empty after development reload

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?

like image 204
violarium Avatar asked Sep 14 '16 19:09

violarium


1 Answers

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.

like image 104
violarium Avatar answered Sep 29 '22 05:09

violarium