我的 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)