服务器发送事件期间线程卡在 Flask 应用程序中

问题描述 投票:0回答:0

我的 flask 应用程序使用 gunicorn,我也使用 nginx 作为反向代理。 一个进程写入一个文本文件,我希望在更新文件时使用服务器发送事件将该文本文件的内容实时发送到前端。我在我的应用程序中创建了一个从前端调用的端点,接收到的内容在前端使用。 这是我的终点-

@app.route('/custompoint')
def stream():
   def eventStream(text_file):
       try:
           with open(text_file, 'r') as f:
               while True:
                   line = f.readline()
                   if not line:                             #skipping if no new line has been added to the text file
                       sleep(0.1)
                       continue
                   x = 'data: {}\n\n'.format(line)
                   yield x                                  #using yield instead of return so that only the new line added is returned
                   sleep(1)
       except:
           return 'data: {}\n\n'.format("Error while opening text file")
  
   if ((not isfile(text_file)) and ('user' in session)):
       response = Response('data: {}\n\n'.format("User in session but textfile not found"))
   elif 'user' not in session:
       response = Response('data: {}\n\n'.format("User not in session"))
   else:
       response = Response(eventStream(text_file))

   #some headers for server-sent event to work
   response.mimetype="text/event-stream"
   response.headers["Content-Type"] = "text/event-stream"
   response.headers["X-Accel-Buffering"] = "no"
   response.headers["Connection"] = ""
   return response

这就是我在 javascript 中调用此端点的地方-

//this function closes the connection to the endpoint from frontend
function close_conn(eventSource){
   eventSource.close();
}

function status(eventSource){
   eventSource.onmessage = function(e) {
       someElement.innerHTML =  e.data;
   };
}

//initiating the connection to my endpoint
eventSource = new EventSource("/custompoint");
status(eventSource);

//will call this to close the connection after some conditions have been met
if(after_some_time){
    close_conn(eventSource);
}

注意:在我的应用程序中,默认情况下所有连接都使用 http/1.1

一段时间后,我注意到在连接关闭后,在服务器端执行我的端点的线程仍然处于活动状态。它可能仍在尝试读取文本文件。我不确定是不是因为我使用了发电机“产量”,所以它无法正常关闭。

Que:如果连接已关闭,我如何从我的视图函数中检查然后停止后端脚本的执行?

或任何其他方式,以便我可以实现相同的目标。使用会话变量对我不起作用。

附加信息,如果有帮助: 一段时间后我的 webapp 卡住了,我必须重新启动我的服务器,杀死所有这些卡住的进程/线程才能再次工作。 进程树大概是这样的,所有的线程都卡在了最后-

|-gunicorn(612850)---gunicorn(753003)-+
|                                     |-{gunicorn}(753133)
|                                     |-{gunicorn}(753134)
|                                     |-{gunicorn}(753135)
|                                     |-{gunicorn}(819857)
|                                     |-{gunicorn}(1043773)
|                                     |-{gunicorn}(1391575)
|                                     |-{gunicorn}(1392022)
|                                     |-{gunicorn}(1405038)
|                                     |-{gunicorn}(1408632)
|                                     |-{gunicorn}(1428053)
|                                     `-{gunicorn}(1438487)

很少有线程的堆栈跟踪停留在 -

select(0, NULL, NULL, NULL, {tv_sec=0, tv_usec=0}) = 0 (Timeout)
select(0, NULL, NULL, NULL, {tv_sec=3599, tv_usec=999897}

虽然其余线程具有堆栈跟踪,但它们正在等待上面的线程完成 -

futex(0x289f580, FUTEX_WAIT_PRIVATE, 0, NULL

gunicorn(lsof)的打开文件列表显示类似-

gunicorn 753003    73u     IPv4 58861104       0t0        TCP localhost:postgres->localhost:52698 (ESTABLISHED)
gunicorn 753003    74u     IPv4 58861229       0t0        TCP localhost:postgres->localhost:52702 (ESTABLISHED)
gunicorn 753003    75u     IPv4 58889563       0t0        TCP localhost:postgres->localhost:52734 (CLOSE_WAIT)
gunicorn 753003    76u     IPv4 58889569       0t0        TCP localhost:postgres->localhost:52738 (ESTABLISHED)
gunicorn 753003    77u     IPv4 58890084       0t0        TCP localhost:postgres->localhost:52764 (ESTABLISHED)
gunicorn 753003    78u     IPv4 58890882       0t0        TCP localhost:postgres->localhost:52828 (CLOSE_WAIT)
gunicorn 753003    79u     IPv4 58934600       0t0        TCP localhost:postgres->localhost:52980 (CLOSE_WAIT)
gunicorn 753003    80u     IPv4 58934602       0t0        TCP localhost:postgres->localhost:52984 (CLOSE_WAIT)
gunicorn 753003    81u     IPv4 58934603       0t0        TCP localhost:postgres->localhost:52986 (CLOSE_WAIT)
gunicorn 753003    82u     IPv4 58934608       0t0        TCP localhost:postgres->localhost:52988 (CLOSE_WAIT)
python multithreading flask gunicorn server-sent-events
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.