Mam konfigurację, w której Tornado służy jako rodzaj przejścia dla pracowników. Żądanie jest odbierane przez Tornado, które wysyła tę prośbę do N pracowników, agreguje wyniki i odsyła je do klienta. Które działa dobrze, z wyjątkiem sytuacji, gdy z jakiegoś powodu upłynął limit czasu —, a następnie mam wyciek pamięci.Wyciek pamięci Tornado na porzuconych połączeniach
Mam konfigurację podobną do tej, która Pseudokod:
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()
Co robię źle? Skąd bierze się wyciek pamięci?
Nie podoba mi się to "jeśli len (odpowiedzi) == len (pracownicy):" - czy jesteś pewien, że aplikacja zawsze tu przychodzi? Spróbuj zarejestrować próby zestawienia żądań i pomyślnych prób. –
@Nikolay: w prawo, AFAIK, Tornado używa wywołania zwrotnego zarówno do sukcesu, jak i błędu. W ten sposób jestem pewien, że niezależnie od tego, ilu pracowników zawiodło, zawsze otrzymuję tyle odpowiedzi. Nie jestem pewien, co się dzieje, gdy klient anuluje wniosek. – vartec
Także, jeśli masz więcej niż 10 pracowników, a wszystkie z nich umierają z powodu przekroczenia limitu czasu - masz okres, w którym tornado nie może utworzyć nowego połączenia - nie wiem, jak zachowuje się w tym momencie. Spróbuj zagrać z argumentem 'max_clients'. –