scheduling asynchronous delayed execution

N

Nick Brown

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
 
R

Richard Conroy

[Note: parts of this message were removed to make it a legal post.]

Check out resque-scheduler:

http://github.com/bvandenbos/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

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)
 
R

Robert Klemme

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

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
 
N

Nick Brown

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

Mat Brown

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

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.
 
R

Robert Klemme

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top