SeriousM
SeriousM

Reputation: 3541

Running delayed_job inside the main web process

Can i run delayed_job or similar schedule frameworks inside of the web server eg. thin or unicorn? If yes how do i start it? (code example would be very cool!)

The reason is that i want to save money during my application is just in a build-up phase and it is hosted on heroku.

Upvotes: 2

Views: 1123

Answers (3)

brauliobo
brauliobo

Reputation: 6323

You can run it inside a separate worker of Unicorn, so it shares memory with the master process and get restarted together with the app.

See https://gist.github.com/brauliobo/11298486

Upvotes: 0

accounted4
accounted4

Reputation: 1705

Officially

No, there is no supported way to run delayed_jobs asynchronously within the web framework. From the documentation on running jobs, it looks like the only supported way to run a job is to run a rake task or the delayed job script. Also, it seems conceptually wrong to bend a Rack server, which was designed to handle incoming client requests, to support pulling tasks off of some queue somewhere.

The Kludge

That said, I understand that saving money sometimes trumps being conceptually perfect. Take a look at these rake tasks. My kludge is to create a special endpoint in your Rails server that you hit periodically from some remote location. Inside this endpoint, instantiate a Delayed::Worker and call .start on it with the exit_on_complete option. This way, you won't need a new dyno or command.

Be warned, it's kind of a kludgy solution and it will tie up one of your rails processes until all delayed jobs are complete. That means unless you have other rails processes, all incoming requests will block until this queue request is finished. Unicorn provides facilities to spawn worker processes. Whether or not this solution will work will also depend on your jobs and how long they take to run and your application's delay tolerances.

Edit

With the spawn gem, you can wrap your instantiation of the Delayed::Worker with a spawn block, which will cause your jobs to be run in a separate process. This means your rails process will be available to serve web requests immediately instead of blocking while delayed jobs are run. However, the spawn gem has some dependencies on ActiveRecord and I do not know what DB/ORM you are using.

Here is some example code, because it's becoming a bit hazy:

class JobsController < ApplicationController
  def run
    spawn do
      @options = {} # youll have to get these from that rake file
      Delayed::Worker.new(@options.merge(exit_on_complete: true)).start
    end
  end
end

Upvotes: 3

Tom
Tom

Reputation: 68

Here's a link to a similar question:

Is it feasible to run multiple processeses on a Heroku dyno?

Bear in mind, as the post says, if you're only using one web dyno, it will be shut down if there's no traffic going to it.

In a similar vein, you might look into:

http://blog.codeship.io/2012/05/06/Unicorn-on-Heroku.html

To save on the need for multiple web dynos whilst you're building your app (although it's still subject to the above shutdown issue).

I would suggest you might look at running on a VPS directly, rather than Heroku (check out the railscast):

http://railscasts.com/episodes/337-capistrano-recipes

Once set up, it's pretty easy to deploy to. Heroku cuts out the devops part for you.

Upvotes: 1

Related Questions