2012-09-08 8 views
6

Robię małą aplikację Sinatra. Wykonuje kilka wywołań Redis, zwraca dane, a następnie wykonuje ostateczne wywołanie Redis, aby zapisać "statystyki".Jak wysłać odpowiedź, ale kontynuować realizację w Sinatrze?

Do tej pory, jeśli chcę zakończyć żądania wcześnie (oparte na wejściu), uważam, że można używać halt:

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

Na samym końcu chcę mieć coś takiego:

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

Czy można wysłać odpowiedź, A następnie zrobić 5 ms redis, aby klient nie musiał czekać? Niezależnie od tego, gdzie i w jaki sposób ustawiam ostateczne wywołanie statystyki, opóźnia wysłanie odpowiedzi o kilka ms - nie może oszukać sinatry.

Można to łatwo wykonać w węźle, ale wystarczy napisać, co chcę zrobić, a zostanie ono uruchomione po wysłaniu odpowiedzi; o ile rozumiem, kod tutaj zablokuje wykonanie na około 5 ms przed cofnięciem odpowiedzi.

Próbowałem używać po .. do filtrów, a one działałyby dobrze oprócz tego, że nie można przekazać im niczego poza danymi w response.body - co oznacza, że ​​nie można przekazać do filtra niczego, co nie jest ". Zostanie wypuszczony! Można uniknąć tego problemu, przypisując zmiennej wartość poza zakresem postu ("/"), jednak przy ponad 100 żądaniach na sekundę, mam nadzieję, że możesz zobaczyć, w jaki sposób zamiana danych poprzez "globale" może stać się ogromnym problemem .

Wydaje się, że jest to coś naprawdę prostego, ale nie mogę znaleźć nic lepszego niż po. .. zrobić filtry w dokumentach.

Czy mogę utworzyć wątek lub coś, co sprawi, że proces redis.hset() nie będzie blokował, czy to zadziała? Wygląda na to, że hakujesz to hardcore.

Dzięki!

Odpowiedz

2

Rozwinięcie zapisu redis powinno działać.

coś takiego:

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

rozwidlone wydaje się błędem w Sinatra na Heroku: *** glibc wykryte *** rubin: podwójne wolne lub korupcji (poprz!): 0x0000000003824b20 *** aplikacja [ web.1]: ======= Śledzenie: ========= aplikacja [web.1]: /lib/libc.so.6(+0x775b6)[0x7fef9d8385b6] aplikacja [sieć .1]: /lib/libc.so.6(cfree+0x73)[0x7fef9d83ee83] –

+0

Czy próbowałeś z Thread.new zamiast fork? –

+0

Macierzyste wątki nie są dostępne w MRI, tylko jRuby i Rubinius. Czy mogę polecić Rubiniusza? –

Powiązane problemy