I wrote an API daemon. It hardly processes requests in the loop (inside processing it can call other services by http and amqp, overload sql database etc). I want to find the best way to make a graceful shutdown for it. So when it receives sigterm or interrupt, it must exit only after finishing current request processing. I don't use threads, but, I'm confused, that some libs can. Like Bunny.
So this is not a deal:
begin
processing @request
rescue Interrupt => _
db.close
end
I thinking about like that:
$gameover = false
trap('INT'){ $gameover = true }
trap('TERM'){ $gameover = true }
class HardApi < Sinatra::Base
before{ lots of code }
after do
if $gameover
db.close
mq.disconnect
log.info{"The end."}
exit 0
end
end
post('/chat/:id') do |chat_id|
BabblerCtrl.new(@request).upload_file(chat_id)
MQService.publish_to_user(@client_id, chat_id, type: :service, :i_file_uploaded)
end
# etc
end
Also Ruby interpreter say that it can't use Mutex from inside trap.
So my question is the global variable the best solution for such flag or there is something like semaphore, that I can setup from trap?
The simple script, that I wrote to test was working, but there's alots of debug of my real program and I'm still not sure that that will work in prod.
A global variable is a fine way to do this, but you can make things more organized:
class HardApi < Sinatra::Base
@@should_exit = false
def self.soft_exit
@@should_exit = true
end
before{ lots of code }
after do
if @@should_exit
# ...
end
end
end
trap('INT'){ HardApi.soft_exit }
trap('TERM'){ HardApi.soft_exit }