Execute Code Once Sinatra Server Is Running

Run code in sinatra after the response has been sent

You can use any solution for background jobs processing. Here is example for Sidekiq usage with Sinatra.

You can try to use Threads as well:

set :threaded, true

post '/' do
request.body.rewind
data = request.body.read
Thread.new do
# data processing staff goes here
end
# here goes response
end

Sinatra app executes during load instead of after run method issued

Okay, I get it. I put the code in a class, but not it a method. Load or require both run open code like this. I need to wrap it in methods, and execute the methods, to do what I want to do.

Sinatra examples, which I followed, don't make this clear and simply avoid the topic. Many are so simple it doesn't make a difference, and some are just coded within the config.ru. I am coming from Rails and, while I knew this from Rails, it didn't make much of a difference since the vast majority of the code already exists in methods.

How to detect, that server is started in Sinatra/Thin

You can use the defined? method to check for this, e.g.

if defined? Rack::Handler::Thin
# We're running under Thin. Do stuff.
else
# nope :(
end

Sinatra - Register startup and shutdown operations

The answer depends on how you need to perform your operations. Does they need to be ran for each ruby process or do they need to be ran just once for the service. I suppose it's once for all the service and in the case of the latest :

You might be tempted to run some code before your Sinatra app is starting but this is not really the behavior you might expect. I'll explain why just after. The workaround would be adding code before your sinatra class like

require "sinatra"
puts "Starting"

get "/" do
...
end

You could add some code to your config.ru too btw, would have the same effect but I don't which one is uglier.

Why is this wrong ? Because when you host your web service, many web server instances will be fired and each one will execute the puts method or your "starting" code. This is correct when you want to initialize things that are local to your app instance, like a database connection but not to initialize things which are shared by all of them.

And about the code firing at its end, well you can't (or maybe you could with some really ugly workaround, but you'll end with the same issue you get with the start).

So the best way to handle on and off operations would be to wrap it within your tasks firing your service.

  1. Run some rake task or ruby script that do your initalization stuff
  2. Start your web server

And to stop it

  1. Run a rake task or ruby script that stops the server
  2. Run your rake task or ruby script that does the cleaning operations.

You can wrap those into a single rake task, by starting your app server directly from ruby, like I did there https://github.com/TactilizeTeam/photograph/blob/master/bin/photograph.

This way you can easily add some code to get ran before starting the service, still keeping it into a single task. With some plumbing, I guess you can fire multiple thin instances and then allow you to start your cluster of thin (or whatever you use) instances and have still one task to rely on.

I'd say that adding a handler to the SIGINT signal could allow you to run some code before exiting. See http://www.ruby-doc.org/core-1.9.3/Signal.html for how to do that. You might want to check if Thin isn't already registering a trap for that signal, I'm not sure if this is handled in the library or in the script used to launch thin ( the "thin" executable that gets in your $PATH).

Another way to handle the exit, would be to have a watchdog process, that check if your cluster is running and could ensure the stop code is being ran if no more instances are running.



Related Topics



Leave a reply



Submit