{"action":"opened","number":176,"pull_request":{"url":"https://api.github.com/repos/gorilla/websocket/pulls/176","id":91289536,"html_url":"https://github.com/gorilla/websocket/pull/176","diff_url":"https://github.com/gorilla/websocket/pull/176.diff","patch_url":"https://github.com/gorilla/websocket/pull/176.patch","issue_url":"https://api.github.com/repos/gorilla/websocket/issues/176","number":176,"state":"open","locked":false,"title":"Don't close FD on write errors","user":{"login":"KiranRG","id":9190852,"avatar_url":"https://avatars.githubusercontent.com/u/9190852?v=3","gravatar_id":"","url":"https://api.github.com/users/KiranRG","html_url":"https://github.com/KiranRG","followers_url":"https://api.github.com/users/KiranRG/followers","following_url":"https://api.github.com/users/KiranRG/following{/other_user}","gists_url":"https://api.github.com/users/KiranRG/gists{/gist_id}","starred_url":"https://api.github.com/users/KiranRG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KiranRG/subscriptions","organizations_url":"https://api.github.com/users/KiranRG/orgs","repos_url":"https://api.github.com/users/KiranRG/repos","events_url":"https://api.github.com/users/KiranRG/events{/privacy}","received_events_url":"https://api.github.com/users/KiranRG/received_events","type":"User","site_admin":false},"body":"We have built a \"streaming\" layer atop gorilla-websocket, that essentially buffers messages before writing out to the wire .. and on the other end, we would \"deserialize\" the payload into individual messages before returning to the application.\r\n\r\nOne of the issues we encountered when using gorilla's websocket implementation was in the following scenario -- we have a streaming client and a streaming server, each with read and write \"pumps\"; the client sends \"requests\" to the the server, which the server receives/processes and sends back \"responses\" to. After the server has sent the last of its \"responses\" (including a final \"done\" response) it closes the connection.\r\n\r\nThe client has a \"write pump\" (that's sending requests) and a \"write pump\" (that's reading/receiving responses). Because the server has gone away, the client encounters an error when doing a write, and the gorilla layer (in the code-path that I have fixed below) automatically/internally closes the connection/FD -- effectively wiping out any buffered responses (including our \"done\" response) from the server, which would have otherwise been available to read.\r\n\r\nIn our scenario, our client re-connects to the server until it gets the \"done\" response -- which it fails to see due to the above bug, causing it to be stalled doing retries for a long time.\r\n\r\nWhat this fix does is to avoid closing the connection on a write-error -- we leave it to the application/user (of gorilla websocket) to call websocket.Close() when done.\r\n\r\nIn our case, for instance, this gives an opportunity to the read-pump to be able to \"drain\" out all available messages (\"responses\", including the \"done\" response), before encountering the error (due to the connection closure) and closing the connection.\r\n","created_at":"2016-10-27T22:06:09Z","updated_at":"2016-10-27T22:06:09Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6556034ae0c8a6c0fc14ece02ee2f46d4935b8ef","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/gorilla/websocket/pulls/176/commits","review_comments_url":"https://api.github.com/repos/gorilla/websocket/pulls/176/comments","review_comment_url":"https://api.github.com/repos/gorilla/websocket/pulls/comments{/number}","comments_url":"https://api.github.com/repos/gorilla/websocket/issues/176/comments","statuses_url":"https://api.github.com/repos/gorilla/websocket/statuses/08e34ffb83d7cac434181142d51d77c0e96007fb","head":{"label":"KiranRG:dont-close-on-write-error","ref":"dont-close-on-write-error","sha":"08e34ffb83d7cac434181142d51d77c0e96007fb","user":{"login":"KiranRG","id":9190852,"avatar_url":"https://avatars.githubusercontent.com/u/9190852?v=3","gravatar_id":"","url":"https://api.github.com/users/KiranRG","html_url":"https://github.com/KiranRG","followers_url":"https://api.github.com/users/KiranRG/followers","following_url":"https://api.github.com/users/KiranRG/following{/other_user}","gists_url":"https://api.github.com/users/KiranRG/gists{/gist_id}","starred_url":"https://api.github.com/users/KiranRG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KiranRG/subscriptions","organizations_url":"https://api.github.com/users/KiranRG/orgs","repos_url":"https://api.github.com/users/KiranRG/repos","events_url":"https://api.github.com/users/KiranRG/events{/privacy}","received_events_url":"https://api.github.com/users/KiranRG/received_events","type":"User","site_admin":false},"repo":{"id":72148485,"name":"websocket","full_name":"KiranRG/websocket","owner":{"login":"KiranRG","id":9190852,"avatar_url":"https://avatars.githubusercontent.com/u/9190852?v=3","gravatar_id":"","url":"https://api.github.com/users/KiranRG","html_url":"https://github.com/KiranRG","followers_url":"https://api.github.com/users/KiranRG/followers","following_url":"https://api.github.com/users/KiranRG/following{/other_user}","gists_url":"https://api.github.com/users/KiranRG/gists{/gist_id}","starred_url":"https://api.github.com/users/KiranRG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KiranRG/subscriptions","organizations_url":"https://api.github.com/users/KiranRG/orgs","repos_url":"https://api.github.com/users/KiranRG/repos","events_url":"https://api.github.com/users/KiranRG/events{/privacy}","received_events_url":"https://api.github.com/users/KiranRG/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/KiranRG/websocket","description":"A WebSocket implementation for Go.","fork":true,"url":"https://api.github.com/repos/KiranRG/websocket","forks_url":"https://api.github.com/repos/KiranRG/websocket/forks","keys_url":"https://api.github.com/repos/KiranRG/websocket/keys{/key_id}","collaborators_url":"https://api.github.com/repos/KiranRG/websocket/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/KiranRG/websocket/teams","hooks_url":"https://api.github.com/repos/KiranRG/websocket/hooks","issue_events_url":"https://api.github.com/repos/KiranRG/websocket/issues/events{/number}","events_url":"https://api.github.com/repos/KiranRG/websocket/events","assignees_url":"https://api.github.com/repos/KiranRG/websocket/assignees{/user}","branches_url":"https://api.github.com/repos/KiranRG/websocket/branches{/branch}","tags_url":"https://api.github.com/repos/KiranRG/websocket/tags","blobs_url":"https://api.github.com/repos/KiranRG/websocket/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/KiranRG/websocket/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/KiranRG/websocket/git/refs{/sha}","trees_url":"https://api.github.com/repos/KiranRG/websocket/git/trees{/sha}","statuses_url":"https://api.github.com/repos/KiranRG/websocket/statuses/{sha}","languages_url":"https://api.github.com/repos/KiranRG/websocket/languages","stargazers_url":"https://api.github.com/repos/KiranRG/websocket/stargazers","contributors_url":"https://api.github.com/repos/KiranRG/websocket/contributors","subscribers_url":"https://api.github.com/repos/KiranRG/websocket/subscribers","subscription_url":"https://api.github.com/repos/KiranRG/websocket/subscription","commits_url":"https://api.github.com/repos/KiranRG/websocket/commits{/sha}","git_commits_url":"https://api.github.com/repos/KiranRG/websocket/git/commits{/sha}","comments_url":"https://api.github.com/repos/KiranRG/websocket/comments{/number}","issue_comment_url":"https://api.github.com/repos/KiranRG/websocket/issues/comments{/number}","contents_url":"https://api.github.com/repos/KiranRG/websocket/contents/{+path}","compare_url":"https://api.github.com/repos/KiranRG/websocket/compare/{base}...{head}","merges_url":"https://api.github.com/repos/KiranRG/websocket/merges","archive_url":"https://api.github.com/repos/KiranRG/websocket/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/KiranRG/websocket/downloads","issues_url":"https://api.github.com/repos/KiranRG/websocket/issues{/number}","pulls_url":"https://api.github.com/repos/KiranRG/websocket/pulls{/number}","milestones_url":"https://api.github.com/repos/KiranRG/websocket/milestones{/number}","notifications_url":"https://api.github.com/repos/KiranRG/websocket/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/KiranRG/websocket/labels{/name}","releases_url":"https://api.github.com/repos/KiranRG/websocket/releases{/id}","deployments_url":"https://api.github.com/repos/KiranRG/websocket/deployments","created_at":"2016-10-27T21:09:18Z","updated_at":"2016-10-27T21:09:19Z","pushed_at":"2016-10-27T21:18:23Z","git_url":"git://github.com/KiranRG/websocket.git","ssh_url":"git@github.com:KiranRG/websocket.git","clone_url":"https://github.com/KiranRG/websocket.git","svn_url":"https://github.com/KiranRG/websocket","homepage":"","size":318,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"gorilla:master","ref":"master","sha":"6257d10a8b2ac6825fa94294e088dc9890ab73d3","user":{"login":"gorilla","id":489566,"avatar_url":"https://avatars.githubusercontent.com/u/489566?v=3","gravatar_id":"","url":"https://api.github.com/users/gorilla","html_url":"https://github.com/gorilla","followers_url":"https://api.github.com/users/gorilla/followers","following_url":"https://api.github.com/users/gorilla/following{/other_user}","gists_url":"https://api.github.com/users/gorilla/gists{/gist_id}","starred_url":"https://api.github.com/users/gorilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gorilla/subscriptions","organizations_url":"https://api.github.com/users/gorilla/orgs","repos_url":"https://api.github.com/users/gorilla/repos","events_url":"https://api.github.com/users/gorilla/events{/privacy}","received_events_url":"https://api.github.com/users/gorilla/received_events","type":"Organization","site_admin":false},"repo":{"id":13624859,"name":"websocket","full_name":"gorilla/websocket","owner":{"login":"gorilla","id":489566,"avatar_url":"https://avatars.githubusercontent.com/u/489566?v=3","gravatar_id":"","url":"https://api.github.com/users/gorilla","html_url":"https://github.com/gorilla","followers_url":"https://api.github.com/users/gorilla/followers","following_url":"https://api.github.com/users/gorilla/following{/other_user}","gists_url":"https://api.github.com/users/gorilla/gists{/gist_id}","starred_url":"https://api.github.com/users/gorilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gorilla/subscriptions","organizations_url":"https://api.github.com/users/gorilla/orgs","repos_url":"https://api.github.com/users/gorilla/repos","events_url":"https://api.github.com/users/gorilla/events{/privacy}","received_events_url":"https://api.github.com/users/gorilla/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/gorilla/websocket","description":"A WebSocket implementation for Go.","fork":false,"url":"https://api.github.com/repos/gorilla/websocket","forks_url":"https://api.github.com/repos/gorilla/websocket/forks","keys_url":"https://api.github.com/repos/gorilla/websocket/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gorilla/websocket/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gorilla/websocket/teams","hooks_url":"https://api.github.com/repos/gorilla/websocket/hooks","issue_events_url":"https://api.github.com/repos/gorilla/websocket/issues/events{/number}","events_url":"https://api.github.com/repos/gorilla/websocket/events","assignees_url":"https://api.github.com/repos/gorilla/websocket/assignees{/user}","branches_url":"https://api.github.com/repos/gorilla/websocket/branches{/branch}","tags_url":"https://api.github.com/repos/gorilla/websocket/tags","blobs_url":"https://api.github.com/repos/gorilla/websocket/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gorilla/websocket/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gorilla/websocket/git/refs{/sha}","trees_url":"https://api.github.com/repos/gorilla/websocket/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gorilla/websocket/statuses/{sha}","languages_url":"https://api.github.com/repos/gorilla/websocket/languages","stargazers_url":"https://api.github.com/repos/gorilla/websocket/stargazers","contributors_url":"https://api.github.com/repos/gorilla/websocket/contributors","subscribers_url":"https://api.github.com/repos/gorilla/websocket/subscribers","subscription_url":"https://api.github.com/repos/gorilla/websocket/subscription","commits_url":"https://api.github.com/repos/gorilla/websocket/commits{/sha}","git_commits_url":"https://api.github.com/repos/gorilla/websocket/git/commits{/sha}","comments_url":"https://api.github.com/repos/gorilla/websocket/comments{/number}","issue_comment_url":"https://api.github.com/repos/gorilla/websocket/issues/comments{/number}","contents_url":"https://api.github.com/repos/gorilla/websocket/contents/{+path}","compare_url":"https://api.github.com/repos/gorilla/websocket/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gorilla/websocket/merges","archive_url":"https://api.github.com/repos/gorilla/websocket/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gorilla/websocket/downloads","issues_url":"https://api.github.com/repos/gorilla/websocket/issues{/number}","pulls_url":"https://api.github.com/repos/gorilla/websocket/pulls{/number}","milestones_url":"https://api.github.com/repos/gorilla/websocket/milestones{/number}","notifications_url":"https://api.github.com/repos/gorilla/websocket/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gorilla/websocket/labels{/name}","releases_url":"https://api.github.com/repos/gorilla/websocket/releases{/id}","deployments_url":"https://api.github.com/repos/gorilla/websocket/deployments","created_at":"2013-10-16T16:41:46Z","updated_at":"2016-10-27T15:49:35Z","pushed_at":"2016-10-27T22:06:09Z","git_url":"git://github.com/gorilla/websocket.git","ssh_url":"git@github.com:gorilla/websocket.git","clone_url":"https://github.com/gorilla/websocket.git","svn_url":"https://github.com/gorilla/websocket","homepage":"","size":318,"stargazers_count":2661,"watchers_count":2661,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":454,"mirror_url":null,"open_issues_count":4,"forks":454,"open_issues":4,"watchers":2661,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/gorilla/websocket/pulls/176"},"html":{"href":"https://github.com/gorilla/websocket/pull/176"},"issue":{"href":"https://api.github.com/repos/gorilla/websocket/issues/176"},"comments":{"href":"https://api.github.com/repos/gorilla/websocket/issues/176/comments"},"review_comments":{"href":"https://api.github.com/repos/gorilla/websocket/pulls/176/comments"},"review_comment":{"href":"https://api.github.com/repos/gorilla/websocket/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/gorilla/websocket/pulls/176/commits"},"statuses":{"href":"https://api.github.com/repos/gorilla/websocket/statuses/08e34ffb83d7cac434181142d51d77c0e96007fb"}},"merged":false,"mergeable":true,"mergeable_state":"clean","merged_by":null,"comments":0,"review_comments":0,"commits":1,"additions":6,"deletions":6,"changed_files":1}}
{"actor":{"display_login":"KiranRG"}}