Sinatra を使用して Web サービスを設計しています。サービスの開始時に特定の操作を実行し、サーバーの停止時に他の操作を実行する必要があります。
それらの操作をsinatraと完全に統合するにはどうすれば登録できますか?
ありがとう。
答えは、操作をどのように実行する必要があるかによって異なります。Rubyプロセスごとに実行する必要がありますか、それともサービスに対して1回だけ実行する必要がありますか? すべてのサービスに対して1回で、最新の場合は次のようになります。
Sinatra アプリを起動する前に何らかのコードを実行したくなるかもしれませんが、これは実際には期待できる動作ではありません。理由はその直後に説明します。回避策は、次のようなsinatraクラスの前にコードを追加することです
require "sinatra"
puts "Starting"
get "/" do
...
end
config.ru にいくつかのコードを追加することもできますが、同じ効果がありますが、どちらが醜いかはわかりません。
なぜこれが間違っているのですか?Web サービスをホストすると、多くの Web サーバー インスタンスが起動され、それぞれが puts メソッドまたは「開始」コードを実行するためです。これは、データベース接続など、アプリ インスタンスにローカルなものを初期化したいが、それらすべてで共有されているものを初期化したくない場合に適しています。
そして、コードが最後に発火することについては、できません (または、非常に醜い回避策でできるかもしれませんが、最初に発生したのと同じ問題で終了します)。
そのため、オンとオフの操作を処理する最善の方法は、サービスを起動するタスク内にラップすることです。
そしてそれを止めるために
https://github.com/TactilizeTeam/photograph/blob/master/bin/photographで行ったように、アプリ サーバーを Ruby から直接起動することで、これらを 1 つの rake タスクにラップできます。
このようにして、サービスを開始する前に実行するコードを簡単に追加して、サービスを 1 つのタスクにまとめることができます。いくつかの配管があれば、複数のシン インスタンスを起動してから、シン (または使用するもの) インスタンスのクラスターを開始し、依存するタスクを 1 つ持つことができると思います。
SIGINT シグナルにハンドラーを追加すると、終了する前に何らかのコードを実行できるようになると思います。その方法については、 http://www.ruby-doc.org/core-1.9.3/Signal.htmlを参照してください。Thinがそのシグナルのトラップをまだ登録していないかどうかを確認することをお勧めします。これがライブラリまたはthinを起動するために使用されるスクリプトで処理されるかどうかはわかりません( $PATH に入る「thin」実行可能ファイル)。
終了を処理する別の方法として、クラスターが実行されているかどうかを確認し、インスタンスが実行されていない場合は停止コードが実行されていることを確認できるウォッチドッグ プロセスを用意することもできます。