#python #sockets #flask #gevent
#python #сокеты #flask #gevent
Вопрос:
У меня есть возможная утечка соединений при выполнении потоковой передачи с помощью flask и gevent.
Многие соединения на стороне сервера остаются (после их закрытия на стороне клиента) в CLOSE_WAIT
состоянии.
Это происходит не для всех клиентов, а только для некоторых из них (но для этих клиентов это происходит в 100% случаев).
Я использую стандартный код потоковой передачи Flask, ничего особенного, поэтому я говорю, что проблема общая.
Вот мой код:
@app.route('/', defaults={'path': ''}, methods=['GET', 'POST'])
def catch_all(path):
session_id = 'tettris'
if session_id not in sessions:
session = Session()
sessions[session_id] = session
else:
session = sessions[session_id]
session.start()
queue = register_queue()
def events():
try:
if queue:
while True:
for _, data in queue:
yield data
finally:
# THIS POINT HERE IS NEVER BEING REACHED
# FOR SOME CLIENTS, becase the connection
# is getting stuck in the CLOSE_WAIT state
deregister_queue(queue)
if len(queues) == 0:
session.kill()
del sessions[session_id]
return Response(events(), content_type='text/event-stream')
Как вы можете видеть, код тривиален и довольно стандартен.
Я полагаю, что где-то должно быть какое-то условие гонки, потому что, как я уже сказал, не все соединения заканчиваются в CLOSE_WAIT
состоянии.
Я полагаю, что это зависит от стека TCP / IP клиента.
Комментарии:
1. Как завершается
while True:
цикл?2. Я подозреваю, что удаление этого исправит эту проблему.
3. @VPfB: Это стандартный метод: когда дескриптор закрыт, и вы пытаетесь выполнить запись в него, вы получите исключение, а затем вы выйдете из цикла. Смотрите, например, это flask.pocoo.org/snippets/116 , как я уже сказал, это обычное дело, и, конечно, это не корень проблемы с утечкой CLOSE_WAIT
4. @IgorChubin Спасибо за объяснение. Я не знал об этом взаимодействии между Flask и функцией потокового просмотра из краткого ознакомления с документами.
5. @hafiz031: Я не решил проблему; Я просто сообщил об этом вверх по течению, и это было принято как ошибка; и что я сделал, я просто переключил этот проект, где он у меня был, на Go, и я должен признать (даже будучи фанатом Flask), это день и ночь. Так что я даже не знаю, что случилось с этой ошибкой, но вполне возможно, что она все еще там