I put my cron task in a module, and then in my Sinatra server.
module Cron
scheduler = Rufus::Scheduler.new
scheduler.every "30m", :first => :now do
run_cmd('git pull')
puts "pulled the repo!!!"
end
end
class MyServer < Sinatra::Base
include Cron
end
The entry point for the app is unicorn (unicorn config/config.ru -p 9393 -c config/unicorn.rb
), and in unicorn.rb
, there's this line
worker_processes 7
Because of this, git pull is running seven times every 30 minutes, and pulled the repo!!!
is printed seven times.
Is there a way I can run this task only in one thread? I tried putting it in unicorn.rb above worker_processes 7
line but I'm not sure if that's the best place for this code to live in.
Unicorn is a multi-process (not multi-threaded) Rack server. There's no native support for executing a specific code path only in one of the worker processes.
However, you can work around that by saving the worker number after fork into an environment variable and then checking its value in your application code.
In config/unicorn.rb
use
after_worker_ready do |server, worker|
ENV["WORKER_NR"] = worker.nr.to_s
end
In your Sinatra app do:
if unicorn_worker_nr == "0"
scheduler.every "30m", :first => :now do
...
end
end
def unicorn_worker_nr
ENV["WORKER_NR"]
end