Tengo una configuración en la que Tornado se utiliza como una especie de paso para trabajadores. Tornado recibe la solicitud, que envía esta solicitud a N trabajadores, agrega los resultados y los envía al cliente. Lo cual funciona bien, excepto cuando por algún motivo se agota el tiempo de espera —, entonces tengo una pérdida de memoria.Fuga de memoria de tornado en conexiones caídas
Tengo una configuración similar a la que este pseudocódigo:
workers = ["http://worker1.example.com:1234/",
"http://worker2.example.com:1234/",
"http://worker3.example.com:1234/" ...]
class MyHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def post(self):
responses = []
def __callback(response):
responses.append(response)
if len(responses) == len(workers):
self._finish_req(responses)
for url in workers:
async_client = tornado.httpclient.AsyncHTTPClient()
request = tornado.httpclient.HTTPRequest(url, method=self.request.method, body=body)
async_client.fetch(request, __callback)
def _finish_req(self, responses):
good_responses = [r for r in responses if not r.error]
if not good_responses:
raise tornado.web.HTTPError(500, "\n".join(str(r.error) for r in responses))
results = aggregate_results(good_responses)
self.set_header("Content-Type", "application/json")
self.write(json.dumps(results))
self.finish()
application = tornado.web.Application([
(r"/", MyHandler),
])
if __name__ == "__main__":
##.. some locking code
application.listen()
tornado.ioloop.IOLoop.instance().start()
¿Qué estoy haciendo mal? ¿De dónde viene la fuga de memoria?
No me gusta esto 'si len (responses) == len (workers):' - ¿estás seguro de que la aplicación siempre llega aquí? Intente registrar intentos para realizar un lote de solicitudes e intentos exitosos. –
@Nikolay: a la derecha, AFAIK, Tornado utiliza una devolución de llamada tanto para el éxito como para el error. Por lo tanto, estoy bastante seguro de que, independientemente de la cantidad de trabajadores que fallaron, siempre recibe muchas respuestas. Lo que no estoy seguro es qué sucede cuando el cliente cancela la solicitud. – vartec
Además, si tiene más de 10 trabajadores, y todos ellos mueren por tiempo de espera, tiene un período de tiempo cuando el tornado no puede crear una nueva conexión, no sé cómo se comporta en este momento. Intenta jugar con el argumento 'max_clients'. –