processi

about processes and engines

rufus-scheduler 2.0.12 released

rufus-scheduler is a thread-based scheduler written in Ruby. It lets you write code like:

require 'rufus-scheduler'

s = Rufus::Scheduler.start_new

s.every '10m' do
  puts 'open the window for the cat'
end

s.at '2012-01-01 12:00' do
  puts 'reminder: wife's birthday'
end

s.cron '0 22 * * 1-5' do
  puts 'activate the security system'
end

s.join # in case of stand-alone script...

The main addition brought by this release is the :mutex attribute when scheduling blocks of code. I was seeing people misusing :blocking => true to exclude block execution overlapping. It works but the scheduler is blocked as well, and crons might get skipped:

s.every '10m', :blocking => true do
  puts 'doing this...'
  sleep 60 * 60 # 1 hour
  puts 'done.'
end

# if the scheduler is in the blocking task above, crons will get skipped...
s.at '2012-01-01 12:00' do
  puts 'do that.'
end

My advice was to use mutexes instead:

$m = Mutex.new

s.every '10m' do
  $m.synchronize do
    puts 'doing this...'
    sleep 60 * 60 # 1 hour
    puts 'done.'
  end
end

# if the scheduler is in the blocking task above, crons will get skipped...
s.at '2012-01-01 12:00' do
  $m.synchronize do
    puts 'do that.'
  end
end

For those of you who use such mutexes and are OK with them wrapping the whole block, rufus-scheduler 2.0.12 introduces the :mutex attribute:

s.every '10m', :mutex => 'my_mutex_name' do
  puts 'doing this...'
  sleep 60 * 60 # 1 hour
  puts 'done.'
end

# if the scheduler is in the blocking task above, crons will get skipped...
s.at '2012-01-01 12:00', :mutex => 'my_mutex_name'  do
  puts 'do that.'
end

Where rufus-scheduler receives a mutex name and manages it for you.

When one wants more control over the granularity, it’s OK to do:

$m = Mutex.new

s.every '10m', :mutex => $m do
  puts 'doing this...'
  sleep 60 * 60 # 1 hour
  puts 'done.'
end

# if the scheduler is in the blocking task above, crons will get skipped...
s.at '2012-01-01 12:00' do
  puts 'do that'
  $m.synchronize do
    puts 'and that.'
  end
end

 

Remember that rufus-scheduler is not a cron replacement. Many thanks to all the people who complained or helped in the development of this piece of software over the years.

 

source: https://github.com/jmettraux/rufus-scheduler
issues: https://github.com/jmettraux/rufus-scheduler/issues
mailing list: http://groups.google.com/group/rufus-ruby
irc: freenode #ruote

 

Written by John Mettraux

October 28, 2011 at 11:27 am

2 Responses

Subscribe to comments with RSS.

  1. Hi John,
    the rufus-scheduler is a great program, it is very cool.
    now i want to do something like that:
    1. the 1st section program check the config document in every 10 minutes;
    2. the 2ed section program using the interval time var gotten from config document to do a schedule,.
    if the interval var is changed in the config document, the 2ed section program should use the new var. the program is in the following, but it doesnt work, please comment, many thanks!

    require ‘rufus/scheduler’

    ti= Time.now.strftime(“%Y-%m-%d %a %H:%M:%S”)
    puts “[#{ti}],start to test ”
    $basic_schedule_workday=”3m”

    s = Rufus::Scheduler::PlainScheduler.start_new
    s.every ‘4m’ do
    read_ini=ReadIni.new
    read_ini.read ‘cfg.ini’
    ti= Time.now.strftime(“%Y-%m-%d %a %H:%M:%S”)
    puts ” [#{ti}]every 4m check ini file to get the $basic_schedule_workday.”

    s.every $basic_schedule_workday do
    ti= Time.now.strftime(“%Y-%m-%d %a %H:%M:%S”)
    puts “[#{ti}],every #{$basic_schedule_workday} print new interval time from ini.”
    end
    end
    s.join

    Edward

    December 1, 2011 at 1:02 am


Comments are closed.