{"action":"created","issue":{"url":"https://api.github.com/repos/nathan-hoad/gbulb/issues/5","repository_url":"https://api.github.com/repos/nathan-hoad/gbulb","labels_url":"https://api.github.com/repos/nathan-hoad/gbulb/issues/5/labels{/name}","comments_url":"https://api.github.com/repos/nathan-hoad/gbulb/issues/5/comments","events_url":"https://api.github.com/repos/nathan-hoad/gbulb/issues/5/events","html_url":"https://github.com/nathan-hoad/gbulb/issues/5","id":140729572,"number":5,"title":"StreamWriter.write() only writes part of data","user":{"login":"sth","id":950517,"avatar_url":"https://avatars.githubusercontent.com/u/950517?v=3","gravatar_id":"","url":"https://api.github.com/users/sth","html_url":"https://github.com/sth","followers_url":"https://api.github.com/users/sth/followers","following_url":"https://api.github.com/users/sth/following{/other_user}","gists_url":"https://api.github.com/users/sth/gists{/gist_id}","starred_url":"https://api.github.com/users/sth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sth/subscriptions","organizations_url":"https://api.github.com/users/sth/orgs","repos_url":"https://api.github.com/users/sth/repos","events_url":"https://api.github.com/users/sth/events{/privacy}","received_events_url":"https://api.github.com/users/sth/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-03-14T16:44:25Z","updated_at":"2016-03-14T21:37:25Z","closed_at":null,"body":"I have a subprocess and write data to its stdin. This works up to a certain amount of data, but stalls for larger amounts. The initial data is written, but after ~500KB it stops and nothing happens anymore.\r\n\r\n```python\r\nimport gbulb; gbulb.install()\r\nimport asyncio, subprocess\r\n\r\n# 1000 rather long lines of input data\r\nindata = ('x' * 10000 + '\\n') * 1000\r\n\r\ndef run():\r\n   proc = yield from asyncio.create_subprocess_exec('sed', '-n', '=', stdin=subprocess.PIPE)\r\n   proc.stdin.write(indata.encode('ascii'))\r\n   proc.stdin.close()\r\n   yield from proc.wait()\r\n\r\nasyncio.get_event_loop().run_until_complete(asyncio.async(run()))\r\n```\r\n\r\nHere the `sed` command prints a number for each input line. It would be expected to count up to 1000, for the 1000 input lines. For me it only counts up to 40-60 and then hangs.\r\n\r\nIt looks like\r\n- When [`proc.stdin.write()`][1] is called, some data is written to the pipe. The remainder is stored in `self._buffer` for later writing.\r\n- [`_write_ready()`][2] is called. It writes some more data (but not all of it). Since it didn't write all data, it doesn't remove itself from the event loop.\r\n- `_write_ready()` is never called again.\r\n\r\nSource of the problem seems to be that the write handle [doesn't have its `repeat` parameter set][3] and therefore [removes itself][4] from the event loop after it was executed for the first time. So no repeated `_write_ready()` calls happen and the remaining data is never written.\r\n\r\nSetting `repeat=True` when the write handle is [created][3] seems to fix the problem, though I don't know if it causes other complications.\r\n\r\n[1]: https://github.com/python/cpython/blob/master/Lib/asyncio/unix_events.py#L483\r\n[2]: https://github.com/python/cpython/blob/master/Lib/asyncio/unix_events.py#L516\r\n[3]: https://github.com/nathan-hoad/gbulb/blob/master/gbulb/glib_events.py#L236\r\n[4]: https://github.com/nathan-hoad/gbulb/blob/master/gbulb/glib_events.py#L100"},"comment":{"url":"https://api.github.com/repos/nathan-hoad/gbulb/issues/comments/196531415","html_url":"https://github.com/nathan-hoad/gbulb/issues/5#issuecomment-196531415","issue_url":"https://api.github.com/repos/nathan-hoad/gbulb/issues/5","id":196531415,"user":{"login":"nathan-hoad","id":332492,"avatar_url":"https://avatars.githubusercontent.com/u/332492?v=3","gravatar_id":"","url":"https://api.github.com/users/nathan-hoad","html_url":"https://github.com/nathan-hoad","followers_url":"https://api.github.com/users/nathan-hoad/followers","following_url":"https://api.github.com/users/nathan-hoad/following{/other_user}","gists_url":"https://api.github.com/users/nathan-hoad/gists{/gist_id}","starred_url":"https://api.github.com/users/nathan-hoad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathan-hoad/subscriptions","organizations_url":"https://api.github.com/users/nathan-hoad/orgs","repos_url":"https://api.github.com/users/nathan-hoad/repos","events_url":"https://api.github.com/users/nathan-hoad/events{/privacy}","received_events_url":"https://api.github.com/users/nathan-hoad/received_events","type":"User","site_admin":false},"created_at":"2016-03-14T21:37:25Z","updated_at":"2016-03-14T21:37:25Z","body":"Hello, thanks for the awesome bug report! I can reproduce this, and setting `repeat=True` does fix your issue, but does also introduce a complication, frustratingly.\r\n\r\nIf you try running this code:\r\n\r\n```import asyncio\r\nimport gbulb\r\n\r\n\r\ndef main():\r\n    gbulb.install()\r\n    loop = gbulb.get_event_loop()\r\n\r\n    loop.run_until_complete(asyncio.open_connection('www.google.com', 80))\r\n\r\n    print('done')\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n```\r\n\r\nYou'll see tracebacks being repeatedly spewed to the terminal, which are caused by setting `repeat=True`. So from your bug report, it seems it needs to be `repeat=True` with some conditions on when to actually stop repeating, I guess. I'll look into this further, but if you have any ideas, I'd be glad to hear them! :)"}}