Ruby Weekly is a weekly newsletter covering the latest Ruby and Rails news.

Backgrounded: A Simple Wrapper for Ruby Background Tasks

By Ric Roberts / July 23, 2009

backgroundedLike Ryan Sonnek, I've dabbled with a few different ways to run background processes in my Ruby apps, even resorting to knocking together my own (far from perfect) solution. As Ryan says on his blog, many popular libraries have complicated interfaces and don't "feel right".

I tend to disagree, however, with his statement that every ruby background job solution sucks, and I'm sure he doesn't really mean it. Although his offering, Backgrounded, is refreshingly simple and concise, it's effectively just a wrapper for other solutions.

With Backgrounded, if you want a certain method to always run in the background, you can specify it like this:

class User
  backgrounded :do_stuff

  def do_stuff
    # do all your work here
  end
end

...and then just call that method in the normal way. The actual background work can be taken care of by a handler of your choice, but delayed_job comes bundled.

Ryan's meta-programming approach for declaring background tasks doubles-up as documentation, and puts the focus on the individual methods rather than requiring you to create separate classes for your jobs.

Get Backgrounded as a gem or download the source from Github.

Comments

  1. Julio Capote says:

    Nice work; I like the automatic handling of methods to background tasks...

    I used a similar interface when I made theman to drive scheduled background workers:
    http://github.com/jcapote/theman/tree/master

  2. Mislav says:

    delayed_job has this exact functionality, although as a method in its own namespace. so what's the catch here?

  3. Lou Zell says:

    "every ruby background job solution sucks"?

    send_later(:do_stuff)
    vs
    do_stuff_backgrounded

    Did we miss something?

  4. Ryan Sonnek says:

    The blog post does a better job explaining this, but the reasons this library exists are because:
    * the API should be clean/concise. the alternative delayed_job API is okay, but not great.
    * testability. none of the libraries I've worked with have been particularly good about working in unit tests.
    * portability. It's simple to implement your own worker queue, and delayed_job is included by default just to help users get up and running. It would be trivial for me to extract that into a separate gem and leave the core as platform agnostic.

    IMO the API is the absolute most critical piece to the puzzle.

  5. Ade says:

    I've used all kinds of background process implementations too, including Backgroundrb and delayed_job. I'm wondering: for tasks that can be run by a rake task, is there any reason NOT to run them using backticks and a forked process? E.g.:

    Kernel.fork { `rake export:begin` }

    We're using this on a project and it seems to work fine, not to mention being very simple to deal with. But if there is a compelling reason not to do this, I'm all ears.

  6. Roman Le NĂ©grate says:

    The intention is good but the implementation is already flawed despite the limited amount of code:

    - Why `foo_backgrounded' instead of the more natural `background(:foo)' (like `send_later')?

    - When `Backgrounded::Model' is included, a bunch of unexpected `include's and `extend's happen at inclusion time and each time `backgrounded' is called... with empty modules! Waste of system memory. Looks like dirt from a code template.

    - Calling `to_s' inside a string interpolation: time to read the Pickaxe.

    - References an module from a shared namespace (`Handler') with the outter module name syntax (`B::Handler' though already inside `B').

    - `Handler' being module containing several handler types, it should be named with the plural form. And those types shouldn't be suffixed with "Handler" as they're already namespaced.

    - Performs an include in `Object' (!).

    - Still, the tests are kind of decent, for now.

Other Posts to Enjoy

Twitter Mentions