-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concept for production deployment? #46
Comments
I’m unfamiliar with how passenger does this stuff. Do they have documentation about running things like sidekick or other background job processors? For ruby-clock it would be very analogous. If you can point me to those docs, then I can suggest something. |
Most other gems like Sidekiq assume they are running as a systemd job - not necessarily on the same host as the webserver. We could document how to set this up. # config/environment.rb
require_relative 'application'
Rails.application.initialize!
CLOCK_LOCK_FILE = "/tmp/clock_process.lock"
CLOCK_LOG_FILE = "log/ruby-clock.log"
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
if forked
if File.exist?(CLOCK_LOCK_FILE)
clock_pid = File.read(CLOCK_LOCK_FILE).to_i
if( clock_pid > 0 && Process.kill(0, clock_pid) rescue false )
next
else
File.delete(CLOCK_LOCK_FILE)
end
end
File.open(CLOCK_LOCK_FILE, 'w') {|file| file.write(Process.pid) }
@clock_pid = spawn("bundle exec clock", out: CLOCK_LOG_FILE, err: CLOCK_LOG_FILE)
Process.detach(@clock_pid)
end
end
# Optional. This will attempt clock shutdown whenever a worker exits, so maybe not ideal
PhusionPassenger.on_event(:stopping_worker_process) do
if @clock_pid && File.exist?(CLOCK_LOCK_FILE)
Process.kill("TERM", @clock_pid)
@clock_pid = nil
File.delete(CLOCK_LOCK_FILE) if File.exist?(CLOCK_LOCK_FILE)
end
end
end The upside is there will be a restart attempt per spawned web worker so if ruby-clock crashes, it'll be restarted. Better would probably be an implementation in config.ru, which is started just once, even by Passenger: # config.ru
require_relative 'config/environment'
use Rack::CommonLogger
CLOCK_LOCK_FILE = "/tmp/clock_process.lock"
CLOCK_LOG_FILE = "log/clock.log"
if File.exist?(CLOCK_LOCK_FILE)
clock_pid = File.read(CLOCK_LOCK_FILE).to_i
if clock_pid > 0 && Process.kill(0, clock_pid) # rescue false
puts "Clock process is already running with PID #{clock_pid}"
else
File.delete(CLOCK_LOCK_FILE)
end
end
unless File.exist?(CLOCK_LOCK_FILE)
@clock_pid = spawn("bundle exec clock", out: CLOCK_LOG_FILE, err: CLOCK_LOG_FILE)
Process.detach(@clock_pid)
File.open(CLOCK_LOCK_FILE, 'w') { |file| file.write(@clock_pid) }
puts "Started clock process with PID #{@clock_pid}"
end
run Rails.application I briefly tested the second approach with the Puma web server and it seems to work:
|
ruby-clock assumes to be run analogously as sidekiq - are you avoiding this to save money, or was that not clear? i don't know anything about passenger so i can't give much feedback on the proposed code, other then that you should aim to run ruby-clock before forking and to not run it after forking. something you can do is set up a test job every('5 seconds') do
puts "hello p#{Process.pid} t#{Thread.current.object_id}"
end and then boot up with multiple processes and threads and make sure that there is only once instance of ruby clock running |
It's not about saving money, it's about staying simple and contained, even on production. Also, about having multiple independent Rails apps with different Clockfiles on the same machine, which is perfectly possible with Passenger, without having to resort to complex setups like Docker. I already have a working Clockfile and putting the startup code in the |
gotcha! Does your project run a background job processor? How does it run it?
`ps aux | grep #{pid}`.strip.blank? etc 😅 |
Great :-) |
Hi,
I have setup ruby-clock successfully in one project and am now ready to deploy it to a production environment - which, in my case, is an Apache Passenger webserver. I am using 'mina' for deployment, which is easier and faster than Capistrano (which I used before), but that shouldn't matter.
For production environments, what is the concept to also run ruby-clock when the Passenger server boots up my application? How can I automate this, and automate setting it up during deployment? Or do I need to write (possibly system-wide) systemd init scripts to run my cronjobs?
Any ideas?
The text was updated successfully, but these errors were encountered: