2012-09-08 23 views
6

我正在製作一個小型的sinatra應用程序。它會創建一些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})) 

是否可以發送響應,然後執行5 ms的redis寫入,以便客戶端不必等待?無論我在哪裏或如何將最終統計數據放在redis呼叫中,它都會延遲發送某個ms的響應 - 無法欺騙sinatra。

這可以很容易地在Node中完成,但只是寫我想做的事情,它會在響應發送後觸發;據我所知,這裏的代碼會在迴應一個響應之前阻止執行大約5ms。

我試過使用後..做過濾器,他們會正常工作,除了你不能傳遞給他們任何比response.body中的數據任何東西 - 意味着你不能傳遞給過濾器什麼是不是'要輸出! 通過分配給變量範圍之外的變量(「/」)可以避免這個問題,但是每秒有超過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的檢測***紅寶石:雙重釋放或腐敗(上一個!):0x0000000003824b20 *** 應用[ web.1]:======= Backtrace:========= app [web.1]:/lib/libc.so.6(+0x775b6)[0x7fef9d8385b6] app [web .1]:/lib/libc.so.6(cfree+0x73)[0x7fef9d83ee83] –

+0

您是否嘗試過使用Thread.new而不是fork? –

+0

原生線程在MRI上不可用,只有jRuby和Rubinius。我可以推薦Rubinius嗎? –