{"action":"created","issue":{"url":"https://api.github.com/repos/tornadoweb/tornado/issues/2229","repository_url":"https://api.github.com/repos/tornadoweb/tornado","labels_url":"https://api.github.com/repos/tornadoweb/tornado/issues/2229/labels{/name}","comments_url":"https://api.github.com/repos/tornadoweb/tornado/issues/2229/comments","events_url":"https://api.github.com/repos/tornadoweb/tornado/issues/2229/events","html_url":"https://github.com/tornadoweb/tornado/issues/2229","id":284967716,"number":2229,"title":"Reference cycle through Future and Runner can create leak","user":{"login":"pitrou","id":1721820,"avatar_url":"https://avatars2.githubusercontent.com/u/1721820?v=4","gravatar_id":"","url":"https://api.github.com/users/pitrou","html_url":"https://github.com/pitrou","followers_url":"https://api.github.com/users/pitrou/followers","following_url":"https://api.github.com/users/pitrou/following{/other_user}","gists_url":"https://api.github.com/users/pitrou/gists{/gist_id}","starred_url":"https://api.github.com/users/pitrou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pitrou/subscriptions","organizations_url":"https://api.github.com/users/pitrou/orgs","repos_url":"https://api.github.com/users/pitrou/repos","events_url":"https://api.github.com/users/pitrou/events{/privacy}","received_events_url":"https://api.github.com/users/pitrou/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2017-12-28T18:35:40Z","updated_at":"2017-12-29T19:03:29Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"I'm having an infinite coroutine (basically a `while True: ...` wrapped in a `@gen.coroutine`) that seems to create a leak somewhere, even though all external references get cleared. I was scratching my head a bit and came to the following hypothesis: the existence of the `_futures_to_runners` mapping keeps the `Runner` alive until its `Future` gets destroyed. However, if the `Future` itself is for some reason kept alive by the `Runner` (through an arbitrarily complex reference chain), then the cyclic collector isn't able to make out the reference cycle and break it.\r\n\r\nDoes that sound like a reasonable explanation? Does it mean that moving to `await` and `async def` would clear the reference leak (as an external mapping is not needed anymore)?"},"comment":{"url":"https://api.github.com/repos/tornadoweb/tornado/issues/comments/354487114","html_url":"https://github.com/tornadoweb/tornado/issues/2229#issuecomment-354487114","issue_url":"https://api.github.com/repos/tornadoweb/tornado/issues/2229","id":354487114,"user":{"login":"pitrou","id":1721820,"avatar_url":"https://avatars2.githubusercontent.com/u/1721820?v=4","gravatar_id":"","url":"https://api.github.com/users/pitrou","html_url":"https://github.com/pitrou","followers_url":"https://api.github.com/users/pitrou/followers","following_url":"https://api.github.com/users/pitrou/following{/other_user}","gists_url":"https://api.github.com/users/pitrou/gists{/gist_id}","starred_url":"https://api.github.com/users/pitrou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pitrou/subscriptions","organizations_url":"https://api.github.com/users/pitrou/orgs","repos_url":"https://api.github.com/users/pitrou/repos","events_url":"https://api.github.com/users/pitrou/events{/privacy}","received_events_url":"https://api.github.com/users/pitrou/received_events","type":"User","site_admin":false},"created_at":"2017-12-29T19:03:29Z","updated_at":"2017-12-29T19:03:29Z","author_association":"CONTRIBUTOR","body":"> But I think that's because asyncio's tasks won't run unless you schedule them with ensure_future or other means, unlike tornado coroutines with act like a new thread and execute immediately. \r\n\r\nThis is true, though this only makes a difference for the first iteration on the coroutine. After the first yield point, the coroutine is kept alive by a callback somewhere (for example on the IO loop or on another future)."}}
{"actor":{"display_login":"pitrou"}}