veeqo / activejob-uniqueness

Unique jobs for ActiveJob. Ensure the uniqueness of jobs in the queue.
https://devs.veeqo.com/job-uniqueness-for-activejob/
MIT License
265 stars 27 forks source link

SSL error with sidekiq and heroku redis premium #58

Closed sebgrebe closed 1 year ago

sebgrebe commented 1 year ago

I am using activejob-uniqueness together with sidekiq as the background worker as well as redis, deployed on heroku. When using activejob-uniqueness with heroku redis on the mini plan, everything works fine. When using it with heroku redis on the premium-0 plan, I get the following error when trying to enqueue a job that is using activejob-uniqueness's unique :until_executed:

A Redis::CannotConnectError occurred in background at 2023-08-09 15:50:42 +0200 :

 SSL_connect returned=1 errno=0 peeraddr=[omitted] state=error: certificate verify failed (self signed certificate in certificate chain)
 /app/vendor/bundle/ruby/3.2.0/gems/redis-client-0.15.0/lib/redis_client/ruby_connection.rb:138:in `connect_nonblock'

I believe this is the case because on Heroku's premium-0 plan TLS is enforced. This is a known issue when using Sidekiq and Heroku and Heroku's recommendation is to configure the SSL connection to VERIFY_NONE:

  Sidekiq.configure_server do |config|
    config.redis = {
      url: ENV["REDIS_URL"],
      ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }
    }
  end

In fact, when enqueuing other jobs that are not using activejob-uniqueness I do not see the described issue.

I assume the reason is that when activejob-uniqueness is initialised, the Redis configuration for Sidekiq is somehow ignored or overwritten.

I tried to fix this by setting a similar configuration in config/initializers/active_job_uniqueness.rb as follows:

config.redlock_servers = [RedisClient.new(:url => ENV["REDIS_URL"], :ssl_params => { verify_mode: OpenSSL::SSL::VERIFY_NONE }), 'redis://localhost:6379']

but for this I get the following error:

A NoMethodError occurred in background at 2023-08-09 15:38:12 +0200 :

 undefined method `evalsha' for #<RedisClient [REDIS_URL]>
 /app/vendor/bundle/ruby/3.2.0/gems/redlock-1.3.2/lib/redlock/client.rb:171:in `block (2 levels) in lock'
sebgrebe commented 1 year ago

I was almost there. I eventually resolved this by adding the following line to config/initializers/active_job_uniqueness.rb.

config.redlock_servers = [Redis.new(:url => ENV["REDIS_URL"], :ssl_params => { verify_mode: OpenSSL::SSL::VERIFY_NONE })]

Notice the use of Redis.new rather than RedisClient.new. I also had to remove 'redis://localhost:6379' from the array of servers.