4

I'm trying to get my Rails app to process background jobs with Sidekiq and to connect Sidekiq with redis-to-go on Heroku. Here's my Procfile:

web: bundle exec puma -C config/puma.rb
worker: bundle exec -C config/sidekiq.yml

Here's my the Sidekiq.rb intializer file:

require 'sidekiq'

Sidekiq.configure_client do |config|  
  config.redis = { url: ENV['REDIS_PROVIDER'] }
end 

Sidekiq.configure_client do |config|  
   config.redis = { url: ENV['REDIS_PROVIDER'] }
end

The REDIS_PROVIDERvariable is set to REDISTOGO_URL in Heroku. Per the instructions provided here I added an intializer file redis.rb as well. Here are the contents:

uri = URI.parse(ENV["REDIS_PROVIDER"])
REDIS = Redis.new(:url => uri)

I'm getting the following error and not sure how to resolve it. Heroku is also throwing an H10 error

[3] ! Unable to load application: ArgumentError: invalid uri scheme '

/app/vendor/bundle/ruby/2.2.0/gems/redis-3.3.0/lib/redis/client.rb:416:in `_parse_options': invalid uri scheme '' (ArgumentError) 

UPDATE:

I rolled back to a previous version on Heroku and removed the redis gem from the gemfile, removed the redis intializer file, and the app is no longer crashing. However background jobs still aren't working and I'm getting these errors in the log:

heroku/worker.1:  Starting process with command `bundle exec -C config/sidekiq.yml`
heroku/worker.1:  State changed from starting to up
app/worker.1:  bundler: command not found: -C 
heroku/worker.1:  Process exited with status 127 
heroku/worker.1:  State changed from up to crashed 
app/worker.1:  Install missing gem executables with `bundle install` 

Why is the system not accepting the config parameter causing the worker to crash?

The error of the invalid uri scheme persists:

app/web.1:  Completed 500 Internal Server Error in 303ms (ActiveRecord: 0.0ms) 
app/web.1:  ArgumentError (invalid uri scheme ''): 

sidekiq.yml file

# Sample configuration file for Sidekiq.
# Options here can still be overridden by cmd line args.
# Place this file at config/sidekiq.yml and Sidekiq will
# pick it up automatically.
---
:verbose: false
:concurrency: 10

# Set timeout to 8 on Heroku, longer if you manage your own systems.

:timeout: 8

# Sidekiq will run this file through ERB when reading it so you can
# even put in dynamic logic, like a host-specific queue.
# http://www.mikeperham.com/2013/11/13/advanced-sidekiq-host-specific-queues/
:queues:
  - critical
  - default
  - low

# you can override concurrency based on environment

production: :concurrency: 25 staging: :concurrency: 10

Jarrel09
  • 335
  • 2
  • 17

2 Answers2

4

TL;DR; If you have problems with Sidekiq / Redis locally, define the redis URI as SIDEKIQ_REDIS_URL=redis://localhost:6379

The docs say that Sidekiq will try to connect to localhost:6379 which is probably true, but they're missing one small details. The URI scheme is not http or https, but redis

In my config I'm trying to pass a concrete SIDEKIQ_REDIS_URL that I set in my .env file

Sidekiq.configure_server do |config|
    config.redis = { url: ENV.fetch('SIDEKIQ_REDIS_URL'), size: 12, network_timeout: 5 }
end

Now, if you don't declare the SIDEKIQ_REDIS_URL in the .env it won't work, of course. What's more, it will fail even if you add the default URI:

SIDEKIQ_REDIS_URL=localhost:6379

It will complain about the URI scheme

It seems that the URI scheme is not http or https, but redis:

SIDEKIQ_REDIS_URL=redis://localhost:6379

luigi7up
  • 5,779
  • 2
  • 48
  • 58
0

I was able to correct a failing Heroku deploy and ArgumentError: invalid uri scheme '' error in my app (Rails 6, Ruby 2.7.2) by changing the redis URL references in both redis.rb and sidekiq.rb to the same Redis Cloud ENV variable.

Stack trace was:

remote:        Running: rake assets:precompile
remote:        rake aborted!
remote:        ArgumentError: invalid uri scheme ''
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/redis-4.2.2/lib/redis/client.rb:436:in `_parse_options'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/redis-4.2.2/lib/redis/client.rb:84:in `initialize'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/redis-4.2.2/lib/redis.rb:62:in `new'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/redis-4.2.2/lib/redis.rb:62:in `initialize'
remote:        /tmp/build_961a7a51/config/initializers/redis.rb:4:in `new'
remote:        /tmp/build_961a7a51/config/initializers/redis.rb:4:in `<top (required)>'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:318:in `load'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:318:in `block in load'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:291:in `load_dependency'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:318:in `load'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/engine.rb:666:in `block in load_config_initializer'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.4/lib/active_support/notifications.rb:182:in `instrument'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/engine.rb:665:in `load_config_initializer'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/engine.rb:625:in `block (2 levels) in <class:Engine>'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/engine.rb:624:in `each'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/engine.rb:624:in `block in <class:Engine>'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/initializable.rb:32:in `instance_exec'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/initializable.rb:32:in `run'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/initializable.rb:61:in `block in run_initializers'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/initializable.rb:50:in `each'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/initializable.rb:50:in `tsort_each_child'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/initializable.rb:60:in `run_initializers'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/application.rb:363:in `initialize!'
remote:        /tmp/build_961a7a51/config/environment.rb:5:in `<top (required)>'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/zeitwerk-2.4.0/lib/zeitwerk/kernel.rb:34:in `require'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/zeitwerk-2.4.0/lib/zeitwerk/kernel.rb:34:in `require'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:324:in `block in require'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:291:in `load_dependency'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:324:in `require'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/application.rb:339:in `require_environment!'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/railties-6.0.3.4/lib/rails/application.rb:523:in `block in run_tasks_blocks'
remote:        /tmp/build_961a7a51/vendor/bundle/ruby/2.7.0/gems/sprockets-rails-3.2.2/lib/sprockets/rails/task.rb:61:in `block (2 levels) in define'
remote:        Tasks: TOP => environment
remote:        (See full trace by running task with --trace)
remote:
remote:  !
remote:  !     Precompiling assets failed.
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote:
remote:  !     Push failed

Once I changed all redis url references to the Redis Cloud URL in my Heroku config, my app deployed successfully:

redis.rb

if ENV["REDISCLOUD_CRIMSON_URL"]
    $redis = Redis.new(:url => ENV["REDISCLOUD_CRIMSON_URL"])
end

sidekiq.rb

require 'sidekiq/web'
    
if Rails.env.development?
  Sidekiq.configure_server do |config|
    config.redis = { url: 'redis://localhost:6379' }
  end
end

if Rails.env.production?
    Sidekiq.configure_client do |config|
        config.redis = { url: ENV['REDISCLOUD_CRIMSON_URL'], size: 1, network_timeout: 5 }
    end

    Sidekiq.configure_server do |config|
        pool_size = (Sidekiq.options[:concurrency] + 2)
        config.redis = { url: ENV['REDISCLOUD_CRIMSON_URL'], size: pool_size, network_timeout: 5 }
    end

    Sidekiq::Extensions.enable_delay!
end

REDIS_URL and REDIS_PROVIDER environment variables are also set to REDISCLOUD_CRIMSON_URL (the variable, not the actual value) in the Heroku settings. Hope this is helpful.

mcmaddox
  • 66
  • 2
  • 9