{"action":"created","issue":{"url":"https://api.github.com/repos/grpc/grpc-go/issues/238","labels_url":"https://api.github.com/repos/grpc/grpc-go/issues/238/labels{/name}","comments_url":"https://api.github.com/repos/grpc/grpc-go/issues/238/comments","events_url":"https://api.github.com/repos/grpc/grpc-go/issues/238/events","html_url":"https://github.com/grpc/grpc-go/issues/238","id":93577039,"number":238,"title":"http2client.Write ConnectionError semantics -- possible at-most-once violation","user":{"login":"andres-erbsen","id":918403,"avatar_url":"https://avatars.githubusercontent.com/u/918403?v=3","gravatar_id":"","url":"https://api.github.com/users/andres-erbsen","html_url":"https://github.com/andres-erbsen","followers_url":"https://api.github.com/users/andres-erbsen/followers","following_url":"https://api.github.com/users/andres-erbsen/following{/other_user}","gists_url":"https://api.github.com/users/andres-erbsen/gists{/gist_id}","starred_url":"https://api.github.com/users/andres-erbsen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andres-erbsen/subscriptions","organizations_url":"https://api.github.com/users/andres-erbsen/orgs","repos_url":"https://api.github.com/users/andres-erbsen/repos","events_url":"https://api.github.com/users/andres-erbsen/events{/privacy}","received_events_url":"https://api.github.com/users/andres-erbsen/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-07-07T16:50:06Z","updated_at":"2015-07-21T22:12:21Z","closed_at":"2015-07-21T22:12:21Z","body":"I am concerned that there might be an at-most-once violation in the client.go retry loop. I have not tried to trigger it, and probably won't have time to on the immediate future. It may be worth looking at though, just to be sure -- accidentally doubling an RPC call can be pretty bad. Here is my understanding of the code right now:\r\n\r\nhttps://github.com/grpc/grpc-go/blob/master/call.go#L170 calls sendRequest in a loop, retrying if it returns transport.ConnectionError. sendRequest calls http2client.Write without wrapping the returned error. http2client.Write can return transport.ConnectionError after sending the request (https://github.com/grpc/grpc-go/blob/master/transport/http2_client.go#L463).\r\n\r\nNow, the question is whether if http2client.Write returning transport.ConnectionError guarantees that that the server will not process the write? Can we be sure that a write that looks failed to the client actually means that the server does not get the entire request (and handle it)? Because if it does, and the error is returned to client.go, which retries, the RPC would get executed twice. And this would not be how one would want to call \"Dispense20Dollars()\"."},"comment":{"url":"https://api.github.com/repos/grpc/grpc-go/issues/comments/123494379","html_url":"https://github.com/grpc/grpc-go/issues/238#issuecomment-123494379","issue_url":"https://api.github.com/repos/grpc/grpc-go/issues/238","id":123494379,"user":{"login":"iamqizhao","id":10121772,"avatar_url":"https://avatars.githubusercontent.com/u/10121772?v=3","gravatar_id":"","url":"https://api.github.com/users/iamqizhao","html_url":"https://github.com/iamqizhao","followers_url":"https://api.github.com/users/iamqizhao/followers","following_url":"https://api.github.com/users/iamqizhao/following{/other_user}","gists_url":"https://api.github.com/users/iamqizhao/gists{/gist_id}","starred_url":"https://api.github.com/users/iamqizhao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iamqizhao/subscriptions","organizations_url":"https://api.github.com/users/iamqizhao/orgs","repos_url":"https://api.github.com/users/iamqizhao/repos","events_url":"https://api.github.com/users/iamqizhao/events{/privacy}","received_events_url":"https://api.github.com/users/iamqizhao/received_events","type":"User","site_admin":false},"created_at":"2015-07-21T22:12:21Z","updated_at":"2015-07-21T22:12:21Z","body":"rpc is identified with a unique id. retry will issue a brand-new rpc with a different id. Let me know if I missed something."}}