{"action":"created","issue":{"url":"https://api.github.com/repos/grpc/grpc/issues/9360","repository_url":"https://api.github.com/repos/grpc/grpc","labels_url":"https://api.github.com/repos/grpc/grpc/issues/9360/labels{/name}","comments_url":"https://api.github.com/repos/grpc/grpc/issues/9360/comments","events_url":"https://api.github.com/repos/grpc/grpc/issues/9360/events","html_url":"https://github.com/grpc/grpc/issues/9360","id":201214650,"number":9360,"title":"Python thread throwing exception when passed a stream as arg","user":{"login":"sulliwane","id":1733686,"avatar_url":"https://avatars.githubusercontent.com/u/1733686?v=3","gravatar_id":"","url":"https://api.github.com/users/sulliwane","html_url":"https://github.com/sulliwane","followers_url":"https://api.github.com/users/sulliwane/followers","following_url":"https://api.github.com/users/sulliwane/following{/other_user}","gists_url":"https://api.github.com/users/sulliwane/gists{/gist_id}","starred_url":"https://api.github.com/users/sulliwane/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sulliwane/subscriptions","organizations_url":"https://api.github.com/users/sulliwane/orgs","repos_url":"https://api.github.com/users/sulliwane/repos","events_url":"https://api.github.com/users/sulliwane/events{/privacy}","received_events_url":"https://api.github.com/users/sulliwane/received_events","type":"User","site_admin":false},"labels":[{"id":168238186,"url":"https://api.github.com/repos/grpc/grpc/labels/python","name":"python","color":"2619ff","default":false},{"id":155504847,"url":"https://api.github.com/repos/grpc/grpc/labels/question","name":"question","color":"800080","default":true},{"id":392770873,"url":"https://api.github.com/repos/grpc/grpc/labels/requires%20reporter%20clarification","name":"requires reporter clarification","color":"800080","default":false}],"state":"open","locked":false,"assignee":{"login":"nathanielmanistaatgoogle","id":10131044,"avatar_url":"https://avatars.githubusercontent.com/u/10131044?v=3","gravatar_id":"","url":"https://api.github.com/users/nathanielmanistaatgoogle","html_url":"https://github.com/nathanielmanistaatgoogle","followers_url":"https://api.github.com/users/nathanielmanistaatgoogle/followers","following_url":"https://api.github.com/users/nathanielmanistaatgoogle/following{/other_user}","gists_url":"https://api.github.com/users/nathanielmanistaatgoogle/gists{/gist_id}","starred_url":"https://api.github.com/users/nathanielmanistaatgoogle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathanielmanistaatgoogle/subscriptions","organizations_url":"https://api.github.com/users/nathanielmanistaatgoogle/orgs","repos_url":"https://api.github.com/users/nathanielmanistaatgoogle/repos","events_url":"https://api.github.com/users/nathanielmanistaatgoogle/events{/privacy}","received_events_url":"https://api.github.com/users/nathanielmanistaatgoogle/received_events","type":"User","site_admin":false},"assignees":[{"login":"nathanielmanistaatgoogle","id":10131044,"avatar_url":"https://avatars.githubusercontent.com/u/10131044?v=3","gravatar_id":"","url":"https://api.github.com/users/nathanielmanistaatgoogle","html_url":"https://github.com/nathanielmanistaatgoogle","followers_url":"https://api.github.com/users/nathanielmanistaatgoogle/followers","following_url":"https://api.github.com/users/nathanielmanistaatgoogle/following{/other_user}","gists_url":"https://api.github.com/users/nathanielmanistaatgoogle/gists{/gist_id}","starred_url":"https://api.github.com/users/nathanielmanistaatgoogle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathanielmanistaatgoogle/subscriptions","organizations_url":"https://api.github.com/users/nathanielmanistaatgoogle/orgs","repos_url":"https://api.github.com/users/nathanielmanistaatgoogle/repos","events_url":"https://api.github.com/users/nathanielmanistaatgoogle/events{/privacy}","received_events_url":"https://api.github.com/users/nathanielmanistaatgoogle/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/grpc/grpc/milestones/45","html_url":"https://github.com/grpc/grpc/milestone/45","labels_url":"https://api.github.com/repos/grpc/grpc/milestones/45/labels","id":1845911,"number":45,"title":"1.1","description":"Soon after GA.","creator":{"login":"nathanielmanistaatgoogle","id":10131044,"avatar_url":"https://avatars.githubusercontent.com/u/10131044?v=3","gravatar_id":"","url":"https://api.github.com/users/nathanielmanistaatgoogle","html_url":"https://github.com/nathanielmanistaatgoogle","followers_url":"https://api.github.com/users/nathanielmanistaatgoogle/followers","following_url":"https://api.github.com/users/nathanielmanistaatgoogle/following{/other_user}","gists_url":"https://api.github.com/users/nathanielmanistaatgoogle/gists{/gist_id}","starred_url":"https://api.github.com/users/nathanielmanistaatgoogle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathanielmanistaatgoogle/subscriptions","organizations_url":"https://api.github.com/users/nathanielmanistaatgoogle/orgs","repos_url":"https://api.github.com/users/nathanielmanistaatgoogle/repos","events_url":"https://api.github.com/users/nathanielmanistaatgoogle/events{/privacy}","received_events_url":"https://api.github.com/users/nathanielmanistaatgoogle/received_events","type":"User","site_admin":false},"open_issues":184,"closed_issues":85,"state":"open","created_at":"2016-06-23T17:58:55Z","updated_at":"2017-01-18T03:28:29Z","due_on":null,"closed_at":null},"comments":1,"created_at":"2017-01-17T09:19:54Z","updated_at":"2017-01-18T04:53:42Z","closed_at":null,"body":"If I create the stream object and then pass it to the thread, it will throw:\r\n```python\r\nstream = stub.GetStream(md.Empty())\r\n\r\ndef stream_worker(thestream):\r\n    for elem in thestream:\r\n        logging.info(elem)\r\n\r\nmythread = Thread(\r\n    target=stream_worker,\r\n    args=(stream),\r\n )\r\nmythread.start()\r\n```\r\nthe error:\r\n```\r\nException in thread Thread-2:\r\nTraceback (most recent call last):\r\n  File \"~/.pyenv/versions/3.6.0/lib/python3.6/threading.py\", line 916, in _bootstrap_inner\r\n    self.run()\r\n  File \"~/.pyenv/versions/3.6.0/lib/python3.6/threading.py\", line 864, in run\r\n    self._target(*self._args, **self._kwargs)\r\n  File \"~/myproject/.venv/lib/python3.6/site-packages/grpc/_channel.py\", line 341, in __next__\r\n    return self._next()\r\n  File \"~/myproject/.venv/lib/python3.6/site-packages/grpc/_channel.py\", line 335, in _next\r\n    raise self\r\ngrpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.CANCELLED, Cancelled)>\r\n```\r\nIf I create the stream in the thread, then no problem:\r\n```python\r\ndef stream_worker():\r\n    stream = stub.GetStream(md.Empty())\r\n    for elem in thestream:\r\n        logging.info(elem)\r\n\r\nmythread = Thread(\r\n    target=stream_worker,\r\n )\r\nmythread.start()\r\n```\r\n@nathanielmanistaatgoogle Any idea why it's not possible to start the thread with the stream already created as an argument? \r\nthanks!"},"comment":{"url":"https://api.github.com/repos/grpc/grpc/issues/comments/273382622","html_url":"https://github.com/grpc/grpc/issues/9360#issuecomment-273382622","issue_url":"https://api.github.com/repos/grpc/grpc/issues/9360","id":273382622,"user":{"login":"sulliwane","id":1733686,"avatar_url":"https://avatars.githubusercontent.com/u/1733686?v=3","gravatar_id":"","url":"https://api.github.com/users/sulliwane","html_url":"https://github.com/sulliwane","followers_url":"https://api.github.com/users/sulliwane/followers","following_url":"https://api.github.com/users/sulliwane/following{/other_user}","gists_url":"https://api.github.com/users/sulliwane/gists{/gist_id}","starred_url":"https://api.github.com/users/sulliwane/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sulliwane/subscriptions","organizations_url":"https://api.github.com/users/sulliwane/orgs","repos_url":"https://api.github.com/users/sulliwane/repos","events_url":"https://api.github.com/users/sulliwane/events{/privacy}","received_events_url":"https://api.github.com/users/sulliwane/received_events","type":"User","site_admin":false},"created_at":"2017-01-18T04:53:42Z","updated_at":"2017-01-18T04:53:42Z","body":"So basically I have a class **GrpcClient** that wraps the grpc stub methods, and all of its streaming methods will first get the stream, and then delegate the ```for elem in stream``` loop into a thread, using ```add_worker(stream)```:\r\n```python\r\nclass GrpcClient:\r\n    def __init__(self):\r\n        self.__stub = self.get_grpc_stub()\r\n\r\n    def get_grpc_stub(self):\r\n        auth_plugin = GrpcAuthPlugin()\r\n        metadata_auth = grpc.metadata_call_credentials(auth_plugin, None)\r\n        ssl_creds = grpc.ssl_channel_credentials(None, None, None)\r\n        channel_creds = grpc.composite_channel_credentials(\r\n            ssl_creds,\r\n            metadata_auth,\r\n        )\r\n        channel = grpc.secure_channel(\r\n            self.server_url,\r\n            channel_creds,\r\n        )\r\n        return md.SmartwinFuturesMdStub(channel)\r\n\r\n    def add_worker(self, stream):\r\n        def stream_worker(thestream):\r\n            for elem in thestream:\r\n                logging.info(elem)\r\n        mythread = Thread(\r\n            target=stream_worker,\r\n            args=(stream),\r\n        )\r\n        mythread.start()\r\n\r\n    def getStream(self):\r\n        stream = stub.GetStream(md.Empty())\r\n        self.add_worker(stream)\r\n\r\n\"\"\" The main loop \"\"\"\"\r\nmyClient = GrpcClient()\r\nmyClient.getStream()\r\n```\r\nI don't think that my stub is going out of scope as it is attached to the grpcClient instance (which is living in the main thread).\r\n\r\nBut I will try to come up with a code sample that makes my problem reproducible (my mistake is probably less obvious than I thought) and I'll update the issue after that."}}
{"actor":{"display_login":"sulliwane"}}