0.03
No commit activity in last 3 years
No release in over 3 years
There's a lot of open issues
Delayed Action is a controller concern that lets you queue long running requests in a DRY fashion to avoid timeouts
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
 Dependencies

Runtime

>= 4
 Project Readme

Delayed Action

Add asynchronous queuing to your HTTP requests with one line, via a controller concern.

The code:

class ArticlesController < ApplicationController
   include DelayedAction
   
   delayed_action [:show] 
   
   def show
     
   end
end

Sample Project

https://github.com/mvcodeclub/da_test

Who needs this

Many requests (reports, admin requests, data dumps,) often take longer than a typical HTTP timeout, and it is quite tedious to have to queue things up. The code looks identical to a normal page request, the only difference is that it's expected to take a longer time to execute. Right now, you are forced to package things up into ActiveJob or other queuing mechanisms manually, and there's lots of duplicated code.

It should be easy to switch between a queued request and a normal synchronous HTTP request.

Some Scenarios:

  • You are receiving lots of timeouts in your application because your queries run longer than your timeout settings, this is the gem for you.
  • A common scenario is running your app on Heroku, you may receive RackTimeout or Heroku H13 errors.
  • You often send these requests via email to users, even though it's awkward and non-standard. Users are generally fine to wait 30 seconds or even a few minutes, and it's easier to just keep the tab open in your browser than to have to check your email.

Most existing solutions encourage you to package up your request as an ActiveJob or similar, and then do a bunch of boilerplate work to unwrap things and show your request.

Rather than tediously rewriting your controller method as a background job, just add this gem and one statement and it will get packaged up as a background job and will run when it's completed.

Prerequisites

  • Rails 4
  • ActiveJob
  • A queue provider, such as DelayedJob or Resque

NOTE: This will not work and cause bad things to happen if you try to use the default inline ActiveJob provider

How to use:

Add to your gemfile: gem "delayed_action"

Install the Migration rake delayed_action:install:migrations

Run the migration rake db:migrate

Add a delayed_action to your controller

class ArticlesController < ApplicationController
   include DelayedAction
   
   delayed_action [:show] # the show method will be queued
   
   def index
   
   end
   
   def show # use this as normal
   
   end
end

Todo:

  • Better "Refresh the page" UI needed.
  • Conditional (:if / :unless) blocks would be nice to turn it on / off
  • Expiration of requests
  • Test under load

Example:

class AccountController < ApplicationController

  delayed_action [:run_report]

  def run_report
    # this takes a long time and fails!
    @report = @account.run_really_long_report
  end

end

How it works

DelayedAction intercepts calls to actions you specify. If it finds one, it queues up a request to a job which will run the action on a job queue. It then redirects to your page, with the UUID of the result.

The request runs on the thread that services the ActiveJob queue, not the web thread.

If it sees the UUID on the querystring, it loads the resulting HTML from the database.

It uses app.get to call your functions, and passes on most of the cookies and environment variables to the request so it can be authenticated.

Gotchas

Don't use ActiveJob's default (ActiveJobInline) as this will probably cause a deadlock. Queues need to run out of process.

All of your requests are stored in the DelayedActionResults table. This could get large, and there's no cleanup functionality currently. You have to clean it up yourself

You need to think about security.

It only currently works on GET requests (not POST etc)

Features:

  • Works with ActiveRecord
  • Work with DelayedJob / Postgres
  • Supports Rack::Timeout
  • Work with configurable to any queue or ActiveJob
  • Works with any mime-type

How to report bugs

Please use our github issues page to report bugs or feature requests