{"action":"created","issue":{"url":"https://api.github.com/repos/grpc/grpc-java/issues/2409","repository_url":"https://api.github.com/repos/grpc/grpc-java","labels_url":"https://api.github.com/repos/grpc/grpc-java/issues/2409/labels{/name}","comments_url":"https://api.github.com/repos/grpc/grpc-java/issues/2409/comments","events_url":"https://api.github.com/repos/grpc/grpc-java/issues/2409/events","html_url":"https://github.com/grpc/grpc-java/issues/2409","id":187967204,"node_id":"MDU6SXNzdWUxODc5NjcyMDQ=","number":2409,"title":"BlockingStub returns iterator that cannot be closed","user":{"login":"jonnyzzz","id":256431,"node_id":"MDQ6VXNlcjI1NjQzMQ==","avatar_url":"https://avatars3.githubusercontent.com/u/256431?v=4","gravatar_id":"","url":"https://api.github.com/users/jonnyzzz","html_url":"https://github.com/jonnyzzz","followers_url":"https://api.github.com/users/jonnyzzz/followers","following_url":"https://api.github.com/users/jonnyzzz/following{/other_user}","gists_url":"https://api.github.com/users/jonnyzzz/gists{/gist_id}","starred_url":"https://api.github.com/users/jonnyzzz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jonnyzzz/subscriptions","organizations_url":"https://api.github.com/users/jonnyzzz/orgs","repos_url":"https://api.github.com/users/jonnyzzz/repos","events_url":"https://api.github.com/users/jonnyzzz/events{/privacy}","received_events_url":"https://api.github.com/users/jonnyzzz/received_events","type":"User","site_admin":false},"labels":[{"id":192846364,"node_id":"MDU6TGFiZWwxOTI4NDYzNjQ=","url":"https://api.github.com/repos/grpc/grpc-java/labels/docs","name":"docs","color":"eb6420","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/grpc/grpc-java/milestones/12","html_url":"https://github.com/grpc/grpc-java/milestone/12","labels_url":"https://api.github.com/repos/grpc/grpc-java/milestones/12/labels","id":1932796,"node_id":"MDk6TWlsZXN0b25lMTkzMjc5Ng==","number":12,"title":"Next","description":"","creator":{"login":"ejona86","id":2811396,"node_id":"MDQ6VXNlcjI4MTEzOTY=","avatar_url":"https://avatars2.githubusercontent.com/u/2811396?v=4","gravatar_id":"","url":"https://api.github.com/users/ejona86","html_url":"https://github.com/ejona86","followers_url":"https://api.github.com/users/ejona86/followers","following_url":"https://api.github.com/users/ejona86/following{/other_user}","gists_url":"https://api.github.com/users/ejona86/gists{/gist_id}","starred_url":"https://api.github.com/users/ejona86/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ejona86/subscriptions","organizations_url":"https://api.github.com/users/ejona86/orgs","repos_url":"https://api.github.com/users/ejona86/repos","events_url":"https://api.github.com/users/ejona86/events{/privacy}","received_events_url":"https://api.github.com/users/ejona86/received_events","type":"User","site_admin":false},"open_issues":192,"closed_issues":8,"state":"open","created_at":"2016-08-09T16:41:11Z","updated_at":"2019-10-10T15:38:39Z","due_on":null,"closed_at":null},"comments":8,"created_at":"2016-11-08T11:25:01Z","updated_at":"2019-10-10T16:14:05Z","closed_at":null,"author_association":"NONE","body":"I use a blocking sub for a method that returns a stream of messages. The return type of it is `Iterator<T>`. It turns out I cannot make grpc client to end the request (e.g. because of client failure). There are a number of cases where an open connection may stuck in client because of that\r\n\r\nThe implementation uses \r\n`io.grpc.stub.ClientCalls#blockingServerStreamingCall(io.grpc.Channel, io.grpc.MethodDescriptor<ReqT,RespT>, io.grpc.CallOptions, ReqT)`\r\n\r\ncall, which in turn uses `BlockingResponseStream`. There is no way to reach the `io.grpc.ClientCall#cancel` method form the Iterator. Could be nice to wrap an Iterator or make it implement an interface in the similar way as done with ServerStreamObserver/ClientStreamObserver\r\nThe other approach could be to implement `AutoCloseable` from Java with this iterator\r\n\r\nThere is also a comment on the Iterator implementation class\r\n```\r\n  // TODO(ejona86): determine how to allow ClientCall.cancel() in case of application error.\r\n```\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/grpc/grpc-java/issues/comments/540660849","html_url":"https://github.com/grpc/grpc-java/issues/2409#issuecomment-540660849","issue_url":"https://api.github.com/repos/grpc/grpc-java/issues/2409","id":540660849,"node_id":"MDEyOklzc3VlQ29tbWVudDU0MDY2MDg0OQ==","user":{"login":"ejona86","id":2811396,"node_id":"MDQ6VXNlcjI4MTEzOTY=","avatar_url":"https://avatars2.githubusercontent.com/u/2811396?v=4","gravatar_id":"","url":"https://api.github.com/users/ejona86","html_url":"https://github.com/ejona86","followers_url":"https://api.github.com/users/ejona86/followers","following_url":"https://api.github.com/users/ejona86/following{/other_user}","gists_url":"https://api.github.com/users/ejona86/gists{/gist_id}","starred_url":"https://api.github.com/users/ejona86/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ejona86/subscriptions","organizations_url":"https://api.github.com/users/ejona86/orgs","repos_url":"https://api.github.com/users/ejona86/repos","events_url":"https://api.github.com/users/ejona86/events{/privacy}","received_events_url":"https://api.github.com/users/ejona86/received_events","type":"User","site_admin":false},"created_at":"2019-10-10T16:14:05Z","updated_at":"2019-10-10T16:14:05Z","author_association":"MEMBER","body":"@pskiwi, no, that wouldn't work. After the cancellation you need to \"drain\" the Iterator; keep going until you get hasNext() == false. If you have a `while (iter.hasNext()) iter.next();` after the `finally`, then it would work.\r\n\r\nDraining the ThreadlessExecutor from a Context.CancellationListener scares me because of the threading involved.\r\n\r\nIt would be possible to add a close() method to the Iterator (and require you to cast), but in general we're not wild about the blocking iterator API as it is far too hard to use properly. We think the proper fix here is to have a \"real\" blocking API."}}
{"actor":{"display_login":"ejona86"}}