How can I get ActiveJob to enqueue jobs in Sidekiq on Heroku when called from the app (not the console)?
Asked Answered
C

1

24

I'm running Rails 4.2 on Heroku (cedar), Ruby 2.1.6

I've got Sidekiq running locally on Redis with Foreman, and in my app I call Rails' new ActiveJob deliver_later methods like this, inside application_helper.rb:

assigning_user = User.find(object.created_by)
completing_user = User.find(object.completed_by)
if NotificationMailer.assigned_user_completed_todo(object, completing_user, assigning_user).deliver_later
  nn.email_status = "sent"
end

Locally, this works just as intended. Mails show up in the 'mailers' queue and then are processed and delivered using sendgrid.

On heroku run rails console I can trigger it manually, and it works just fine:

Loading production environment (Rails 4.2.1)
irb(main):001:0> a = Account.first
Account Load (1.5ms)  SELECT  "accounts".* FROM "accounts"  ORDER BY     "accounts"."id" ASC LIMIT 1
=> #<Account id: 1, name: "The Prestons", stripe_customer_id: nil, active_until: "2015-06-27 14:50:43", plan: nil, created_at: "2015-04-27 14:50:43", updated_at: "2015-04-27 14:50:43">
irb(main):002:0> NotificationMailer.new_account_created(a).deliver_later
Enqueued ActionMailer::DeliveryJob (Job ID: 7c0ddf9c-6892-4aa9-823e-9954b2a4e642) to Sidekiq(mailers) with arguments: "NotificationMailer", "new_account_created", "deliver_now", gid://raisin/Account/1
=> #<ActionMailer::DeliveryJob:0x007f4d9ed9da58 @arguments=["NotificationMailer", "new_account_created", "deliver_now", #<Account id: 1, name: "The Prestons", stripe_customer_id: nil, active_until: "2015-06-27 14:50:43", plan: nil, created_at: "2015-04-27 14:50:43", updated_at: "2015-04-27 14:50:43">], @job_id="7c0ddf9c-6892-4aa9-823e-9954b2a4e642", @queue_name="mailers">

but if I simply complete actions in my app, the way I would as a user, nothing is ever delivered to the queue... I am totally out of ideas. I am running a worker process. I am connected to the redis cloud server. I can see the sidekiq web dashboard.

What am I not setting? Happy to provide other logs/info, but not sure what else to provide.

My console simply reports the action:

2015-05-14T09:14:37.674095+00:00 heroku[router]: at=info method=POST path="/accounts/1/projects/15/lists/33/items/112" host=www.myapp.com request_id=516db810-8a2c-4fd0-af89-29a59783b0a8 fwd="76.104.193.78" dyno=web.1 connect=1ms service=111ms status=200 bytes=2039
Copacetic answered 14/5, 2015 at 9:38 Comment(2)
Are you starting Sidekiq with -q mailers?Openair
Yes -- forgot to mention that. IN my procfile: worker: bundle exec sidekiq -q default -q mailersCopacetic
C
87

Embarrassingly, it turns out everything's working correctly, and the action I was doing to test email delivery via code would never have sent an email, because the user I was testing it with has email notifications turned off in settings.

Sigh.

But for posterity and for those who are trying to get Sidekiq to work on Heroku with Rails 4.2 and Redis Cloud, here are some pitfalls I encountered: The part that took me the most time to figure out was that in order to get Sidekiq to find your Redis server, you'll need to set the ENV variable IN Heroku (not in your code). So, at the console, first add e.g. rediscloud:

heroku addons:create rediscloud

And then you need to add the URL as an environment variable:

heroku config:set REDIS_PROVIDER=REDISCLOUD_URL

The Sidekiq documentation is super helpful. I used brew install redis to install Redis locally, then redis-server to run the server in a terminal window locally. Added gem 'sidekiq' to the Gemfile and everything worked great in development.

If you add routes as shown here, you'll be able to monitor the queue in your web browser.

Lastly, don't forget that you need to add a worker in your Procfile AND scale up to one worker in Heroku using heroku ps:scale worker=1 -- it won't start just because it's in your Procfile.

Also: when you put Sidekiq in your Procfile, be sure to tell it to process the mailers queue, e.g.

worker: bundle exec sidekiq -q default -q mailers

Copacetic answered 14/5, 2015 at 16:49 Comment(4)
A wonderful summary of enabling Sidekiq in Heroku, thank you for the great writeup!Openair
@jason ...and that from the author of sidekiq... :) yea, good job +1Gentility
Great write-up! Only thing I missed (but I might haven't read the documentation well enough) is that you actually need to add a initialiser for sidekiq in which you define the number of connections to use, like gist.github.com/vindia/7f356499e646898dbeab Without that initialiser, my jobs were stuck in their queue.Seth
Thanks for mentioning the -q mailers option, I had missed thatAlejandro

© 2022 - 2024 — McMap. All rights reserved.