2012-09-08 30 views
6

Tôi đang tạo một ứng dụng sinatra nhỏ. Nó thực hiện một vài cuộc gọi Redis, trả về dữ liệu và sau đó thực hiện cuộc gọi Redis cuối cùng để lưu "số liệu thống kê".Làm thế nào để gửi phản hồi nhưng tiếp tục thực hiện ở Sinatra?

Cho đến nay nếu tôi muốn chấm dứt yêu cầu sớm (dựa trên đầu vào), tôi thấy rằng tôi có thể sử dụng halt:

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

Vào cuối rất Tôi muốn có một cái gì đó như thế này:

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

Có thể gửi câu trả lời và THEN làm 5 ~ ms redis viết, sao cho khách hàng không phải đợi? Không có vấn đề ở đâu hoặc làm thế nào tôi đặt cuộc gọi redis thống kê cuối cùng, nó trì hoãn việc gửi phản ứng của một số ms - không thể lừa Sinatra.

Điều này có thể dễ dàng được thực hiện trong Nút nhưng chỉ viết những gì tôi muốn thực hiện và nó sẽ kích hoạt sau khi phản hồi đã được gửi; theo như tôi hiểu, đoạn mã ở đây sẽ chặn việc thực thi trong khoảng 5ms trước khi quay lại phản hồi.

Tôi đã thử sử dụng sau khi thực hiện các bộ lọc và chúng sẽ hoạt động tốt ngoại trừ việc bạn không thể chuyển cho chúng bất kỳ điều gì khác ngoài dữ liệu trong response.body - nghĩa là bạn không thể chuyển đến bộ lọc bất kỳ thứ gì không phải ' sẽ được xuất ra! Có thể tránh vấn đề này bằng cách gán cho biến ngoài phạm vi bài đăng ("/"), tuy nhiên với hơn 100 yêu cầu mỗi giây, tôi hy vọng bạn có thể thấy cách hoán đổi dữ liệu thông qua "globals" của các loại có thể trở thành một vấn đề lớn .

Nó có vẻ như một cái gì đó thực sự đơn giản nhưng tôi không thể tìm thấy bất cứ điều gì tốt hơn so với sau .. làm bộ lọc trong tài liệu.

Tôi có thể tạo chuỗi hoặc một thứ gì đó để làm cho quá trình redis.hset() không bị chặn không, điều đó có hiệu quả không? Có vẻ như hacking nó hardcore.

Cảm ơn!

Trả lời

2

Việc sắp xếp lại chữ viết sẽ hoạt động.

Something như thế này:

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

forking dường như lỗi trong Sinatra trên Heroku: *** glibc phát hiện *** ruby: đôi miễn phí hoặc tham nhũng (trước!): 0x0000000003824b20 *** ứng dụng [ web.1]: ======= Backtrace: ========= ứng dụng [web.1]: /lib/libc.so.6(+0x775b6)[0x7fef9d8385b6] ứng dụng [web .1]: /lib/libc.so.6(cfree+0x73)[0x7fef9d83ee83] –

+0

Bạn đã thử với Thread.new, thay vì fork? –

+0

Luồng gốc không khả dụng trên MRI, chỉ có jRuby và Rubinius. Tôi có thể giới thiệu Rubinius không? –

Các vấn đề liên quan