{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/42210291","id":42210291,"diff_hunk":"@@ -216,61 +239,57 @@ func (udp *udpProxySocket) ProxyLoop(service proxy.ServicePortName, myInfo *serv\n \t\t\tglog.Errorf(\"ReadFrom failed, exiting ProxyLoop: %v\", err)\n \t\t\tbreak\n \t\t}\n-\t\t// If this is a client we know already, reuse the connection and goroutine.\n-\t\tsvrConn, err := udp.getBackendConn(myInfo.activeClients, cliAddr, proxier, service, myInfo.timeout)\n-\t\tif err != nil {\n-\t\t\tcontinue\n-\t\t}\n-\t\t// TODO: It would be nice to let the goroutine handle this write, but we don't\n-\t\t// really want to copy the buffer.  We could do a pool of buffers or something.\n-\t\t_, err = svrConn.Write(buffer[0:n])\n-\t\tif err != nil {\n-\t\t\tif !logTimeout(err) {\n-\t\t\t\tglog.Errorf(\"Write failed: %v\", err)\n-\t\t\t\t// TODO: Maybe tear down the goroutine for this client/server pair?\n+\n+\t\tfunc(udp *udpProxySocket, activeClients *clientCache, buffer *[bufferSize]byte, n int, cliAddr net.Addr, proxier *Proxier, service proxy.ServicePortName, timeout time.Duration) {\n+\t\t\tactiveClients.mu.Lock()\n+\t\t\tdefer activeClients.mu.Unlock()\n+\n+\t\t\t// If this is a client we know already, reuse the connection and goroutine.\n+\t\t\tsvrConn, found := activeClients.clients[cliAddr.String()]\n+\t\t\tif !found {\n+\t\t\t\t// TODO: This could spin up a new goroutine to make the outbound connection,\n+\t\t\t\t// and keep accepting inbound traffic.\n+\t\t\t\tglog.V(3).Infof(\"New UDP connection from %s\", cliAddr)\n+\t\t\t\tgo connectAndProxy(service, &fakeUDPConn{udp}, cliAddr, \"udp\", proxier, func(in, svrConn net.Conn) {\n+\t\t\t\t\tif err := svrConn.SetDeadline(time.Now().Add(timeout)); err != nil {\n+\t\t\t\t\t\tglog.Errorf(\"SetDeadline failed: %v\", err)\n+\t\t\t\t\t\treturn\n+\t\t\t\t\t}\n+\t\t\t\t\tactiveClients.clients[cliAddr.String()] = svrConn\n+\t\t\t\t\twriteData(svrConn, buffer, n, timeout)","path":"pkg/proxy/userspace/proxysocket.go","position":146,"original_position":146,"commit_id":"8fc7e341986db63a53814bd76e7eee2edbf89a96","original_commit_id":"8fc7e341986db63a53814bd76e7eee2edbf89a96","user":{"login":"thockin","id":5595220,"avatar_url":"https://avatars.githubusercontent.com/u/5595220?v=3","gravatar_id":"","url":"https://api.github.com/users/thockin","html_url":"https://github.com/thockin","followers_url":"https://api.github.com/users/thockin/followers","following_url":"https://api.github.com/users/thockin/following{/other_user}","gists_url":"https://api.github.com/users/thockin/gists{/gist_id}","starred_url":"https://api.github.com/users/thockin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thockin/subscriptions","organizations_url":"https://api.github.com/users/thockin/orgs","repos_url":"https://api.github.com/users/thockin/repos","events_url":"https://api.github.com/users/thockin/events{/privacy}","received_events_url":"https://api.github.com/users/thockin/received_events","type":"User","site_admin":false},"body":"I think this is a problem.  buffer is in the ProxyLoop scope, and will be reused.  Since this runs in a goroutine now, it will race - the ProxyLoop might receive another packet before the old packet is written to the backend.  I think you have to block on a mutex or make a copy of the buffer.","created_at":"2015-10-16T05:44:08Z","updated_at":"2015-10-16T05:44:08Z","html_url":"https://github.com/kubernetes/kubernetes/pull/13423#discussion_r42210291","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13423","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/42210291"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/13423#discussion_r42210291"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13423"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13423","id":43834257,"html_url":"https://github.com/kubernetes/kubernetes/pull/13423","diff_url":"https://github.com/kubernetes/kubernetes/pull/13423.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/13423.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/13423","number":13423,"state":"open","locked":false,"title":"Improve kube-proxy performance by tackling down TODO in  proxysocket.go","user":{"login":"roackb2","id":5952025,"avatar_url":"https://avatars.githubusercontent.com/u/5952025?v=3","gravatar_id":"","url":"https://api.github.com/users/roackb2","html_url":"https://github.com/roackb2","followers_url":"https://api.github.com/users/roackb2/followers","following_url":"https://api.github.com/users/roackb2/following{/other_user}","gists_url":"https://api.github.com/users/roackb2/gists{/gist_id}","starred_url":"https://api.github.com/users/roackb2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/roackb2/subscriptions","organizations_url":"https://api.github.com/users/roackb2/orgs","repos_url":"https://api.github.com/users/roackb2/repos","events_url":"https://api.github.com/users/roackb2/events{/privacy}","received_events_url":"https://api.github.com/users/roackb2/received_events","type":"User","site_admin":false},"body":"At `/pkg/proxy/userspace/proxysocket.go`, in the `tryConnect` function, there's a TODO:\r\n\r\n```go\r\n// TODO: This could spin up a new goroutine to make the outbound connection,\r\n// and keep accepting inbound traffic.\r\n```\r\n In the function `ProxyLoop`, I extract the part of tryConnect to another function and run it as a goroutine,\r\nmakes the `ProxyLoop` able to accept next inbound request immediately instead of waiting the outbound connection to finish.","created_at":"2015-09-01T03:34:30Z","updated_at":"2015-10-16T05:44:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1304a140fef193ec508b971de195805dda4968c3","assignee":{"login":"thockin","id":5595220,"avatar_url":"https://avatars.githubusercontent.com/u/5595220?v=3","gravatar_id":"","url":"https://api.github.com/users/thockin","html_url":"https://github.com/thockin","followers_url":"https://api.github.com/users/thockin/followers","following_url":"https://api.github.com/users/thockin/following{/other_user}","gists_url":"https://api.github.com/users/thockin/gists{/gist_id}","starred_url":"https://api.github.com/users/thockin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thockin/subscriptions","organizations_url":"https://api.github.com/users/thockin/orgs","repos_url":"https://api.github.com/users/thockin/repos","events_url":"https://api.github.com/users/thockin/events{/privacy}","received_events_url":"https://api.github.com/users/thockin/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13423/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13423/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/13423/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/8fc7e341986db63a53814bd76e7eee2edbf89a96","head":{"label":"roackb2:proxysocket","ref":"proxysocket","sha":"8fc7e341986db63a53814bd76e7eee2edbf89a96","user":{"login":"roackb2","id":5952025,"avatar_url":"https://avatars.githubusercontent.com/u/5952025?v=3","gravatar_id":"","url":"https://api.github.com/users/roackb2","html_url":"https://github.com/roackb2","followers_url":"https://api.github.com/users/roackb2/followers","following_url":"https://api.github.com/users/roackb2/following{/other_user}","gists_url":"https://api.github.com/users/roackb2/gists{/gist_id}","starred_url":"https://api.github.com/users/roackb2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/roackb2/subscriptions","organizations_url":"https://api.github.com/users/roackb2/orgs","repos_url":"https://api.github.com/users/roackb2/repos","events_url":"https://api.github.com/users/roackb2/events{/privacy}","received_events_url":"https://api.github.com/users/roackb2/received_events","type":"User","site_admin":false},"repo":{"id":39437788,"name":"kubernetes","full_name":"roackb2/kubernetes","owner":{"login":"roackb2","id":5952025,"avatar_url":"https://avatars.githubusercontent.com/u/5952025?v=3","gravatar_id":"","url":"https://api.github.com/users/roackb2","html_url":"https://github.com/roackb2","followers_url":"https://api.github.com/users/roackb2/followers","following_url":"https://api.github.com/users/roackb2/following{/other_user}","gists_url":"https://api.github.com/users/roackb2/gists{/gist_id}","starred_url":"https://api.github.com/users/roackb2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/roackb2/subscriptions","organizations_url":"https://api.github.com/users/roackb2/orgs","repos_url":"https://api.github.com/users/roackb2/repos","events_url":"https://api.github.com/users/roackb2/events{/privacy}","received_events_url":"https://api.github.com/users/roackb2/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/roackb2/kubernetes","description":"Container Cluster Manager from Google","fork":true,"url":"https://api.github.com/repos/roackb2/kubernetes","forks_url":"https://api.github.com/repos/roackb2/kubernetes/forks","keys_url":"https://api.github.com/repos/roackb2/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/roackb2/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/roackb2/kubernetes/teams","hooks_url":"https://api.github.com/repos/roackb2/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/roackb2/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/roackb2/kubernetes/events","assignees_url":"https://api.github.com/repos/roackb2/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/roackb2/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/roackb2/kubernetes/tags","blobs_url":"https://api.github.com/repos/roackb2/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/roackb2/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/roackb2/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/roackb2/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/roackb2/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/roackb2/kubernetes/languages","stargazers_url":"https://api.github.com/repos/roackb2/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/roackb2/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/roackb2/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/roackb2/kubernetes/subscription","commits_url":"https://api.github.com/repos/roackb2/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/roackb2/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/roackb2/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/roackb2/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/roackb2/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/roackb2/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/roackb2/kubernetes/merges","archive_url":"https://api.github.com/repos/roackb2/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/roackb2/kubernetes/downloads","issues_url":"https://api.github.com/repos/roackb2/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/roackb2/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/roackb2/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/roackb2/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/roackb2/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/roackb2/kubernetes/releases{/id}","created_at":"2015-07-21T09:54:20Z","updated_at":"2015-07-21T09:54:28Z","pushed_at":"2015-10-06T07:57:57Z","git_url":"git://github.com/roackb2/kubernetes.git","ssh_url":"git@github.com:roackb2/kubernetes.git","clone_url":"https://github.com/roackb2/kubernetes.git","svn_url":"https://github.com/roackb2/kubernetes","homepage":"http://kubernetes.io","size":112661,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"kubernetes:master","ref":"master","sha":"107d0f6d946b5cfeed2e976d866e738ec340d780","user":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"repo":{"id":20580498,"name":"kubernetes","full_name":"kubernetes/kubernetes","owner":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubernetes/kubernetes","description":"Container Cluster Manager from Google","fork":false,"url":"https://api.github.com/repos/kubernetes/kubernetes","forks_url":"https://api.github.com/repos/kubernetes/kubernetes/forks","keys_url":"https://api.github.com/repos/kubernetes/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubernetes/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubernetes/kubernetes/teams","hooks_url":"https://api.github.com/repos/kubernetes/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/kubernetes/kubernetes/events","assignees_url":"https://api.github.com/repos/kubernetes/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/kubernetes/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/kubernetes/kubernetes/tags","blobs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubernetes/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubernetes/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/kubernetes/kubernetes/languages","stargazers_url":"https://api.github.com/repos/kubernetes/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/kubernetes/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/kubernetes/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/kubernetes/kubernetes/subscription","commits_url":"https://api.github.com/repos/kubernetes/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubernetes/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubernetes/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/kubernetes/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubernetes/kubernetes/merges","archive_url":"https://api.github.com/repos/kubernetes/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubernetes/kubernetes/downloads","issues_url":"https://api.github.com/repos/kubernetes/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/kubernetes/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/kubernetes/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubernetes/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/kubernetes/kubernetes/releases{/id}","created_at":"2014-06-06T22:56:04Z","updated_at":"2015-10-16T02:48:40Z","pushed_at":"2015-10-16T05:42:38Z","git_url":"git://github.com/kubernetes/kubernetes.git","ssh_url":"git@github.com:kubernetes/kubernetes.git","clone_url":"https://github.com/kubernetes/kubernetes.git","svn_url":"https://github.com/kubernetes/kubernetes","homepage":"http://kubernetes.io","size":465568,"stargazers_count":10723,"watchers_count":10723,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2722,"mirror_url":null,"open_issues_count":2051,"forks":2722,"open_issues":2051,"watchers":10723,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13423"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/13423"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/13423"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/13423/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13423/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13423/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/8fc7e341986db63a53814bd76e7eee2edbf89a96"}}}}