Tornado を介して長いデータベースの結果セットをストリーミングしたいと考えています。クエリ全体をメモリにロードするのは現実的ではないため、明らかにサーバーカーソルが必要です。
だから私は次のコードを持っています:
class QueryStreamer(RequestHandler):
def get(self):
cursor.execute("Select * from ...")
chunk = cursor.fetch(1000)
while chunk:
self.write(chunk)
self.flush()
chunk = cursor.fetch(1000)
self.finish()
cursor.close()
誰かが私のリクエストを最後まで読まなかったら? (すなわちcurl ... |head
)、get
メソッドはどこにもデータをストリーミングし続けます。SIGPIPE
私は、ある時点で取得してデータベースカーソルを閉じることを期待しています(何もせずに最後まで実行しません)。
Tornado で書き込みエラーをキャッチするにはどうすればよいですか?
更新:回答の提案に従って、次のことを試しました:
import tornado.ioloop
import tornado.web
import time
class PingHandler(tornado.web.RequestHandler):
def get(self):
for i in range(600):
self.write("pong\n")
self.flush()
time.sleep(1)
print "pong"
self.finish()
print "ponged"
def on_connection_close(self):
print "closed"
if __name__ == "__main__":
application = tornado.web.Application([ ("/ping", PingHandler), ])
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
このファイルをターミナル 1 で実行し、ターミナル 2 で呼び出します。
curl -s http://localhost:8888/ping
最初の応答の後、CTRL-C を押しました。しかし、ターミナル 1 では、喜んで「ポン」を鳴らし続け、on_connection_close
呼び出されることはありません。
結論 - まだ機能しません。