Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is sleep() a good idea for the main loop of a job-scheduling app

I'm writing a job-scheduling app in Ruby for my work (primarily to move files using various protocol at a given frequency)

My main loop looks like this :

while true do
  # some code to launch the proper job
  sleep CONFIG["interval"]
end

It's working like a charm, but I'm not really sure if it is safe enough as the application might run on a server with cpu-intensive software running.

Is there another way to do the same thing, or is sleep() safe enough in my case ?

like image 553
Yoann Le Touche Avatar asked Jul 24 '09 18:07

Yoann Le Touche


3 Answers

Any time I feel the need to block, I use an event loop; usually libev. Here is a Ruby binding:

http://rev.rubyforge.org/rdoc/

Basically, sleep is perfectly fine if you want your process to go to sleep without having anything else going on in the background. If you ever want to do other things, though, like sleep and also wait for TCP connections or a filehandle to become readable, then you're going to have to use an event loop. So, why not just use one at the beginning?

The flow of your application will be:

main {
   Timer->new( after => 0, every => 60 seconds, run => { <do your work> } )
   loop();
}

When you want to do other stuff, you just create the watcher, and it happens for you. (The jobs that you are running can also create watchers.)

like image 173
jrockway Avatar answered Oct 05 '22 05:10

jrockway


Using sleep is likely OK for quick and dirty things. But for things that need a bit more robustness or reliability I suggest that sleep is evil :) The problem with sleeping is that the thread is (I'm assuming Windows here...) is truly asleep - the scheduler will not run the thread until some time after sleep interval has passed.

During this time, the thread will not wake up for anything. This means it cannot be canceled, or wake up to process some kind of event. Of course, the process can be killed, but that doesn't give the sleeping thread an opportunity to wake up and clean anything up.

I'm not familiar with Ruby, but I assume it has some kind of facility for waiting on multiple things. If you can, I suggest that instead of using sleep, you waint on two things\

  1. A timer that wakes the thread periodically to do its work.
  2. An event that is set when he process needs to cancel or quite (trapping control-C for example).

It would be even better if there is some kind of event that can be used to signal the need to do work. This would avoid polling on a timer. This generally leads to lower resource utilization and a more responsive system.

like image 20
Foredecker Avatar answered Oct 05 '22 05:10

Foredecker


If you don't need an exact interval, then it makes sense to me. If you need to be awoken at regular times without drift, you probably want to use some kind of external timer. But when you're asleep, you're not using CPU resources. It's the task switch that's expensive.

like image 26
Scott Whitlock Avatar answered Oct 05 '22 03:10

Scott Whitlock