views:

31

answers:

1

Is there a way to limit the number of instances of a rake task?

I have a rake task for reading emails that runs every 5 mins as a cron job.

Sometimes the rake tasks takes more than 5 mins to complete and another rake task is launched before it finishes.

There are hacky workarounds to check ps -Af inside the rake file but I am looking for cleaner way to limit launching multiple instances of the rake tasks similar to how the daemon gem does.

Checking emails is just an example, I have several such rake tasks that involve polling multiple servers.

A: 

Still can't find a super elegant way, so I resorted to saving a unique file for each rake task.

This is how the rake task looks now -

run_unique_rake(__FILE__) do
     puts "\n is running\n"
     sleep(40)
end

here is run_unique_rake

def self.run_unique_rake(file)    
    path = RAILS_ROOT + "/" + CONFIG['rake_log'] + "/" + File.basename(file)

     unless File.exists?(path)
        `touch #{path}`
         yield if block_given?
         `rm #{path}`
     end
end

Still hoping for an elegant way within rake to limit to a single instance.

Sid
Your approach is a good one, though you have a race condition between testing existence and doing the 'touch'. Get around that by doing File.open(path, File::CREAT|File::EXCL) {} instead. The file will be created, unless it already existed in which case EEXIST will be raised. Also, instead of back-tick rm, use: File.unlink(path) which will be much more efficient; and put the unlink after an 'ensure' ( begin; yield; ensure; File.unlink(path); end )
Heath
thanks! In my case the cron job runs once every hour so the race conditions is unlikely. I will definitely incorporate the great suggestions about using the File object and adding an ensure case.
Sid