Scheduling asynchronous delayed execution

What is the best way to schedule something for delayed asynchronous
execution? Basically, I want to say “in 20 seconds, execute this
function / block / proc / lambda / webhook or whatever”.

Also: this will be used by a rack-based web app, so I need a solution
that will keep working if Passenger restarts instances of the
application. Would a Thread.new(delay) {|delay| sleep delay; …} type
of solution work in such a scenario? Does using Thread like this consume
lots of memory?

How have you solved this in the past? I would like to avoid installing
daemons if possible.

I was thinking of doing something like below, but I’m not sure it will
be reliable in a web app environment:

def call_async(code, delay=0)
Thread.new(delay, code) {|d,c| sleep d; c.call}
end

Check out resque-scheduler:

Generally you’ll want to use a standalone daemon to do any sort of
background work; doing it in threads / forking considered harmful in
Rails.

Mat

On Fri, Feb 26, 2010 at 7:53 PM, Mat B. [email protected] wrote:

On Fri, Feb 26, 2010 at 14:50, Nick B. [email protected] wrote:

How have you solved this in the past? I would like to avoid installing
daemons if possible.

Nick,
there’s a lot of options out there, virtually all of them use a
background
process and
are not thread based. You got BackgroundRb, Workling, Starling,
DelayedJob
etc.

There are a lot of implementations of this (too many IMO, it would be
nice
to see
some kind of emergent winner here, this is a very common activity).

They tend to differentiate on their core implementation technologies:
cron
based,
table based, memcache based, Queue based etc.

There are a couple of writeups comparing them. I would go check them
out.
(Sorry I dont have any links to hand)

On 02/26/2010 08:50 PM, Nick B. wrote:

How have you solved this in the past? I would like to avoid installing
daemons if possible.

I was thinking of doing something like below, but I’m not sure it will
be reliable in a web app environment:

def call_async(code, delay=0)
Thread.new(delay, code) {|d,c| sleep d; c.call}
end

Probably not - at least if you do not have control over the process.
For a one off solution you could do

def execute_delayed(sec,&b)
fork do
$stdin.close
$stdout.close
$stderr.close
sleep sec
b.call
end
end

Demonizing the child is probably also a good idea. If you want to
schedule recurring tasks you probably want to use a more robust solution
/ framework.

Kind regards

robert

Thanks everyone. Most of these solutions seem to be for Rails, though.
What is the best solution when using plain-old-ruby?

On 27.02.2010 23:14, Nick B. wrote:

Thanks everyone. Most of these solutions seem to be for Rails, though.
What is the best solution when using plain-old-ruby?

My suggestion was completely Rails agnostic.

Kind regards

robert

On Sat, Feb 27, 2010 at 17:14, Nick B. [email protected] wrote:

Thanks everyone. Most of these solutions seem to be for Rails, though.
What is the best solution when using plain-old-ruby?

Posted via http://www.ruby-forum.com/.

Most queueing solutions are not Rails-specific (Workling being an
exception, I believe). And the advice not to do this using
threads/forks really applies across the board of web apps, not just in
Rails apps.