写入关闭的连接时,Windows上的Flask / Waitress不会产生错误

时间:2019-02-26 20:09:12

标签: python-2.7 flask waitress

我正在通过waitress.serve(app, send_bytes=1)运行Flask应用。如果客户端关闭连接,我将尝试实现停止长时间运行的SQL查询的功能(例如,按浏览器中的“停止”按钮)。

我遇到了一个完全相同的问题:Stop processing Flask route if request aborted,它建议尝试定期写入连接以查看其是否仍然打开。 (我尝试写0字节甚至更进一步,我试图每秒写一个1字节的字符串“ q”。)但是当我在应用程序中实现它时,它不会产生任何“套接字关闭”或“连接”如果浏览器在等待响应时按下“停止”,则会显示“关闭”错误。

即,预期的行为是客户端每秒收到一次“ q”直到获得完整响应,并且python控制台输出是“从队列中获取”,然后是“连接仍然有效,队列为空”,每秒重复一次,直到按下浏览器中的“停止”按钮并发生某种异常为止(我在这里设置了几个异常处理程序,以在应该显示的位置捕获它)。但是实际的行为是,在单击浏览器中的“停止”按钮后,python控制台将继续每秒输出“从队列中获取”和“连接仍然有效,队列为空”,直到查询完成,然后“线程:置于队列中”和“从队列中获取”被记录。在任何时候都不会抛出套接字/连接错误。

为了进行比较,在node.js(位于同一台Windows计算机上)中,使用express,req.on('close', () => {console.log('connection closed');})立即检测到浏览器中的“停止”按钮按下。

任何关于为什么这种方式的想法吗?如何检测客户端是否已在Windows的Waitress / Flask中关闭了连接?

query_string = 'xxx'
@app.route('/filter')
def filter_route():
    response_from_filter = lambda filter: json.dumps({
         ...
        })

    def threaded_query(query_str, queue_obj):
        def callable():
            try:
                filter = db.session.execute(query_string)
                queue_obj.put(response_from_filter(filter))
                print "thread: put on queue"
            except Exception as e:
                print e, "thread error"
        return callable
    def generate(queue_obj):
        while True:
            try:
                print "getting from queue"
                result = queue_obj.get(block=True, timeout=1)
                print "got from queue"
                yield result
                return
            except GeneratorExit as ge:
                print "generator exit"
                break
            except Queue.Empty as e:
                print e, "connection still alive, queue empty"
                yield "q"
            except Exception as e:
                print e, "generic exception"

    query_queue = Queue.Queue()
    thread = threading.Thread(target=threaded_query(query_string, query_queue))
    thread.start()
    try:
        return Response(stream_with_context(generate(query_queue)))
    except Exception as e:
        print e, "Response exception"

0 个答案:

没有答案