8

I'm having an issue with sidekiq. Basically we're getting NameError: uninitialized constant on our sidekiq setup which is causing a large number of jobs to fail.

The error log says:

NameError: uninitialized constant GameUser::Lock
/data/@myapp/releases/20130321230952/app/models/game_user.rb:71:in `node_calls_base_get_user'
/data/@myapp/shared/bundled_gems/ruby/1.9.1/gems/sidekiq-2.8.0/lib/sidekiq/processor.rb:45:in `block (3 levels) in process'
/data/@myapp/shared/bundled_gems/ruby/1.9.1/gems/sidekiq-2.8.0/lib/sidekiq/middleware/chain.rb:109:in `call'

The code is here:

# app/models/game_user.rb
def self.node_calls_base_get_user(serial, game_name)
  if Lock.get("user:#{id}") # Set up lock to prevent multiple users to be created      
    Lock.delete("user:#{id}")
  end
  return false
end

Lock is defined in a library:

# lib/lock.rb
class Lock
  def self.get(key)
    lock = CACHE.add("lock:#{key}", 1, 5) # Let lock autoexpire after 5 seconds
    return true
  end
end

And the lib/ folder is automatically loaded with the rest of the configurations.

module Myapp
  class Application < Rails::Application
    ...
    # Custom directories with classes and modules you want to be autoloadable.
    config.autoload_paths += %W(#{config.root}/lib)
    ...    
  end
end

I have no idea why this is happening. It seems to happen more frequently when we deploy, but it seems to happen often enough otherwise.

I've been following the following thread: https://github.com/mperham/sidekiq/issues/331 but it doesn't seem to offer a solution besides adding the lib folder to the autoload_paths.

I'm using:

gem 'rails', '3.2.13' gem 'sidekiq', '>= 2.7.5'

Any help would be greatly apreciated.

Thilo
  • 17,565
  • 5
  • 68
  • 84
roloenusa
  • 761
  • 1
  • 10
  • 19

2 Answers2

10

Add the lib folder to the eager_load_paths. This is different to the autoload_paths. Sidekiq won't load classes on the fly, which is why you get errors when you try to access a constant that wasn't eagerly loaded.

So in your application.rb

config.autoload_paths += %W(#{config.root}/lib)
config.eager_load_paths += %W(#{config.root}/lib)
Chris Aitchison
  • 4,656
  • 1
  • 27
  • 43
  • I've added these paths and am still getting the same error for all my classes. Any other things I could try? – kakubei May 29 '13 at 13:03
  • Unfortunately no. I had to give up and move on to other things, but never solved it, none of the tips here worked for me :( – kakubei Dec 14 '13 at 12:55
  • 1
    @kakubei Even adding lib to eager load won't necessarily solve it, see this thread that includes post from mperham (creator of sidekiq) https://github.com/mperham/sidekiq/issues/789 He recommends you explicitly require it at top of your file – ObjectNameDisplay Mar 09 '17 at 22:03
0

I think the problem here is most likely the load paths as mentioned above.

Note - I'm not sure the autoload_paths option is required as Rails ignores this outside of development mode

Anyway - I was having a similar issue: Although my code was updated, the job kept trying to call old versions of the code.

I eventually worked out that there were workers running that were old. I only noticed because the stack trace showed the sidekiq gem version was 2.15.0, and I'd updated 2.17.0

I killed the other processes and it worked fine

bodacious
  • 6,608
  • 9
  • 45
  • 74