2012-09-08 16 views
6

私は小さなシナトラアプリを作っています。いくつかのRedis呼び出しを行い、データを返し、最後にRedis呼び出しを行い、 "統計"を保存します。Sinatraでレスポンスを送信しても実行を継続する方法は?

私は早く(入力に基づいて)要求を終了したい場合はこれまでのところ、私はhaltを使用できることがわかった。

# code code 
halt send_blank if is_blocked? SETTINGS, host 
# code code 

非常に終わり、私はこのような何かをしたい:

response.body = JSON.generate(outgoing) 
# update user 
STATISTICS.hset('u:' + userID, 'data', JSON.generate({'ip' => request.ip, 'time' => Time.now.to_f.to_s})) 

応答を送信することは可能ですか?クライアントは待機する必要がないように、5msのredis書き込みを実行しますか?最終的な統計情報をどこに置いても、どのようにしてそれを呼び出すかによって、応答の送信が数ms遅れます。シナリオを欺くことはできません。

これはNodeで簡単に行うことができますが、私がやりたいことを書いているだけで、応答が送信された後に起動します。私が理解する限り、ここのコードは約5msの実行をブロックし、応答を返す。

私はafter.doフィルタを使用しようとしましたが、response.bodyのデータ以外のものを渡すことができないという点を除いて、正常に動作します。つまり、フィルタには何も渡せません。 tが出力されます! ポスト( "/")の範囲外の変数に割り当てることでこの問題を回避することは可能ですが、毎秒100件以上のリクエストで、「グローバル」によるデータのスワップが大きな問題になることがわかります。

これは本当にシンプルなようですが、後から何かを見つけることができません。ドキュメント内のフィルタを実行してください。

redis.hset()プロセスをノンブロッキングにするためのスレッドなどを作成できますか?ハードコアをハッキングしているようだ。

ありがとうございます!

答えて

2

redis書き込みをフォークすると効果があります。このような

何か:

response.body = JSON.generate(outgoing) 
fork do 
    # update user 
    redis = Redis.new(:host => "your_host_name", :port => your_port_number) 
    redis.hset('u:' + userID, 'data', JSON.generate({'ip' => request.ip, 'time' => Time.now.to_f.to_s})) 
end 
+0

フォークは、Herokuの上にシナトラのバグには思える:*** glibcの検出***ルビー:ダブル無料または破損(PREV!):0x0000000003824b20 *** アプリ[ web.1]:=======バックトレース:========= app [web.1]:/lib/libc.so.6(+0x775b6)[0x7fef9d8385b6] app [web .1]:/lib/libc.so.6(cfree+0x73)[0x7fef9d83ee83] –

+0

forkの代わりにThread.newを試しましたか? –

+0

ネイティブスレッディングはMRIでは使用できません.jRubyとRubiniusのみです。 Rubiniusをお勧めしますか? –

関連する問題