Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
like image 313
Jason Preston Avatar asked May 14 '15 09:05

Jason Preston


People also ask

Should I use Activejob Sidekiq?

If you build a web application you should minimize the amount of time spent responding to every user; a fast website means a happy user.

What is a worker in Sidekiq?

Workarea applications use Sidekiq as a job queuing backend to perform units of work asynchronously in the background. These jobs, which include search indexing, cache busting, and cleanup of expired data, are defined as workers .


1 Answers

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

like image 165
Jason Preston Avatar answered Oct 23 '22 04:10

Jason Preston