2

I have an idea to write up a small redis wrapper lib for my side project. everything has been looking just great so far. now, I'm trying to bring polish to my configuration, which I'm a little inspired by configuration block code from airbrake project, reference article here

From the start, I got myself rolling immediately to write up the wrapper class and I managed to do so in a timely manner. Up to this point, what I need to do is I'd like to be able to test my configuration code block (config/initializers/redis_cli.rb) in irb or pry.
I'm not sure why my initialisation code, which is placed under rails project config/initializers, is not working in such debugging console environment.

as soon as I instantiated my RedisCli class in the console as to =>

 RedisCli.new

I got an error saying that "NoMethodError: undefined method host' for nil:NilClass from /Users/admin/rails_projects/redis_app/lib/redis_cli.rb:44:inredis_wrapper_options'"

In contrast, it works just great when running on internal web server, web brick. It seems like my RedisCli initializer didn't get loaded properly in irb.

here is my code:

lib/redis_cli.rb

class RedisCli


  attr_accessor :host,:port,:db,:url,:queue

  class << self
    attr_accessor :configuration
  end

  def self.configure
    self.configuration ||= Configuration.new
    yield(configuration)
  end  

  class Configuration
    attr_accessor :host,:port,:db,:queue

    def initialize

    end
  end 

  def initialize(options={})
    options = redis_wrapper_options(options)
    @host = options[:host]
    @port = options[:port]
    @db = options[:db]
    @queue = options[:queue]
  end

  def url
    @url ||= [@host,@port].reject(&:blank?).join(":") if @url.blank?
    @url       
  end

  def lpush(klass,args)
    redis = Redis.new(:url => url)
    msg = { 'class' => klass,'args' =>  [args],'jid' => SecureRandom.hex(12), 'retry' => true, 'enqueued_at' => Time.now.to_f }
    redis.lpush(@queue,JSON.dump(msg))
  end

  def redis_wrapper_options(overrides = {})      
    {
      :host  => RedisCli.configuration.host,
      :port => RedisCli.configuration.port,    
      :db => RedisCli.configuration.db,        
      :queue   => RedisCli.configuration.queue

    }.merge(overrides || {}).delete_if { |key, value| value.nil? }
  end

end

and my initializer:

config/initializers/redis_cli.rb

RedisCli.configure do |config|
  config.host    = 'redis://localhost'       
  config.port    = '6379'       
  config.db      = ''       
  config.queue   = 'queue:default'                      
end

Could anyone bring me to light on this?

Sarun Sermsuwan
  • 3,608
  • 5
  • 34
  • 46
  • In your def self.configure method, have you tried changing self.configuration to @configuration ||= Configuration.new (for your memoization)? Using self vs @ will reference the variable in different ways and can cause this. (http://stackoverflow.com/questions/1693243/instance-variable-self-vs) Is a good explanation of what occurs for self vs @. – Chris Feb 03 '15 at 17:02
  • Thanks Chris. I made change following to your suggestion, but unfortunately it doesn't seem to work. still getting the same error, "NoMethodError: undefined method host' for nil:NilClass". any thoughts? – Sarun Sermsuwan Feb 03 '15 at 17:10
  • http://stackoverflow.com/questions/18553944/init-some-variables-when-opening-rails-console?lq=1 might be helpful, although I've found that my initializers are *sometimes* run, but not always, on `rails c`. I have no explanation for this behavior. – ptd Feb 03 '15 at 17:31
  • Are you typing `irb`, or something like `bundle exec rails c`? – Brad Werth Feb 03 '15 at 18:13
  • Hi Brad, I usually run "rails c" I also tried 'bundle exec rails c' right after your post, neither seems to work though. however, you've brought me an idea this's most likely a misconfiguration problem application-wide. I'll try the code on a freshly created project. let's see how it works. – Sarun Sermsuwan Feb 03 '15 at 18:47

1 Answers1

2

This was happening to me as well on Rails 5.1.4

The only thing that worked for me was to completely exit Terminal.app, relaunch Terminal.app, and then re-run rails c. Rails Console took about 4-5 seconds longer to initialize than it did before I restarted terminal. It appears that there is some sort a caching going on but that is just a hunch.

Tyler
  • 19,113
  • 19
  • 94
  • 151