Я отбывающий MJPEG потокового ответа от gunicorn с GEvent рабочих. Все работает нормально, но когда соединение завершается клиентом, похоже, что подписчик zeromq не является GC'd и просто продолжает принимать данные изображения.утечка памяти с ответами потока gunicorn GEvent и ZeroMQ
Здесь использование памяти для gunicorn:
Вот исходный код приложения WSGI:
from gevent_zeromq import zmq
context = zmq.Context()
def app(environ, start_response):
if environ['PATH_INFO'] == '/':
subscriber = context.socket(zmq.SUB)
subscriber.connect("ipc:///tmp/camera")
subscriber.setsockopt(zmq.SUBSCRIBE, "")
boundary = "--ipcamera"
status = '200 OK'
headers = [('Content-type', 'multipart/x-mixed-replace;boundary={}'.format(boundary))]
start_response(status, headers)
def get_frames():
while True:
yield subscriber.recv()
return get_frames()
status = '404 NOT FOUND'
headers = []
start_response(status, headers)
return status
Я бегу gunicorn с --max-запросов 5 чтобы помочь, но, очевидно, не является решением. Я даже не знаю, с чего начать выслеживать виновника:/
Что вы делаете, чтобы разрушить сокет, если соединение завершено? – raffian
Ничего. Я предполагал, что все закончит GC'd, когда соединение будет прекращено. Есть ли способ, которым я могу действовать в случае завершения соединения? Wsgiref в std lib вызывает исключение с разбитой трубой, должен ли я попытаться это поймать? –
Да, это может быть решение; поймать исключение, затем выполните 'close()' и 'destroySocket()'. Но удерживайте секунду, является ли 'подписчик' переменной экземпляра? Согласно вышеприведенному коду, это; совместное использование сокетов между параллельными запросами не работает. Вызывается ли 'app()' одновременно из разных потоков? – raffian