{"action":"created","comment":{"url":"https://api.github.com/repos/uber/ringpop/pulls/comments/26865227","id":26865227,"diff_hunk":"@@ -0,0 +1,198 @@\n+// Copyright (c) 2015 Uber Technologies, Inc.\n+//\n+// Permission is hereby granted, free of charge, to any person obtaining a copy\n+// of this software and associated documentation files (the \"Software\"), to deal\n+// in the Software without restriction, including without limitation the rights\n+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n+// copies of the Software, and to permit persons to whom the Software is\n+// furnished to do so, subject to the following conditions:\n+//\n+// The above copyright notice and this permission notice shall be included in\n+// all copies or substantial portions of the Software.\n+//\n+// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n+// THE SOFTWARE.\n+'use strict';\n+\n+var sendPingReq = require('../../lib/swim/ping-req-sender.js');\n+var testRingpopCluster = require('../lib/test-ringpop-cluster.js');\n+\n+// Test helpers\n+function assertNumBadStatuses(assert, res, num) {\n+    var badStatuses = res.pingReqErrs.filter(function filterErr(err) {\n+        return err.type === 'ringpop.ping-req.bad-ping-status';\n+    });\n+\n+    assert.equals(badStatuses.length, num, 'correct number of bad statuses');\n+}\n+\n+function mkNoGossip(cluster) {\n+    var noop = function noop() {\n+    };\n+\n+    cluster.forEach(function eachRingpop(ringpop) {\n+        ringpop.gossip.start = noop;\n+    });\n+}\n+\n+function mkBadPingReqResponder(ringpop) {\n+    ringpop.channel.register('/protocol/ping-req', function protocolPingReq(arg1, arg2, hostInfo, cb) {\n+        cb(null, null, JSON.stringify('badbody'));\n+    });\n+}\n+\n+testRingpopCluster({\n+    tap: function tap(cluster) {\n+        mkNoGossip(cluster);\n+    }\n+}, 'ping-reqs 1 member', function t(bootRes, cluster, assert) {\n+    var ringpop = cluster[0];\n+    var unreachableMember = ringpop.membership.findMemberByAddress(cluster[1].hostPort);\n+\n+    sendPingReq({\n+        ringpop: cluster[0],\n+        unreachableMember: unreachableMember,\n+        pingReqSize: 3\n+    }, function onPingReq(err, res) {\n+        assert.ifErr(err, 'no error occurred');\n+        assert.equal(res.pingReqAddrs.length, 1,\n+            'number of selected ping-req members is correct');\n+        assert.ok(res.pingReqSuccess.address === cluster[2].hostPort,\n+            'successful ping-req response from either member');\n+        assert.end();\n+    });\n+});\n+\n+testRingpopCluster({\n+    size: 5,\n+    tap: function tap(cluster) {\n+        mkNoGossip(cluster);\n+    }\n+}, 'ping-reqs pingReqSize members', function t(bootRes, cluster, assert) {\n+    var ringpop = cluster[0];\n+    var unreachableMember = ringpop.membership.\n+        findMemberByAddress(cluster[1].hostPort);\n+    var pingReqSize = 3;\n+\n+    sendPingReq({\n+        ringpop: cluster[0],\n+        unreachableMember: unreachableMember,\n+        pingReqSize: pingReqSize\n+    }, function onPingReq(err, res) {\n+        assert.ifErr(err, 'no error occurred');\n+        assert.equal(res.pingReqAddrs.length, pingReqSize,\n+            'number of selected ping-req members is correct');\n+        assert.equal(unreachableMember.status, 'alive',\n+            'unreachable member is alive');\n+        assert.end();\n+    });\n+});\n+\n+testRingpopCluster({\n+    size: 5,\n+    tap: function tap(cluster) {\n+        mkNoGossip(cluster);\n+    }\n+}, 'ping-req target unreachable', function t(bootRes, cluster, assert) {\n+    var badRingpop = cluster[4];\n+    badRingpop.destroy();\n+\n+    var ringpop = cluster[0];\n+    var unreachableMember = ringpop.membership.findMemberByAddress(badRingpop.hostPort);\n+    var pingReqSize = 3;\n+\n+    sendPingReq({\n+        ringpop: ringpop,\n+        unreachableMember: unreachableMember,\n+        pingReqSize: pingReqSize\n+    }, function onPingReq(err, res) {\n+        assert.ifErr(err, 'no error occurred');\n+        assertNumBadStatuses(assert, res, pingReqSize);\n+        assert.equals(unreachableMember.status, 'suspect',","path":"test/integration/swim-test.js","position":116,"original_position":116,"commit_id":"b641eb5f2278eb1e66d7d565568e4a2b8f41aac6","original_commit_id":"b641eb5f2278eb1e66d7d565568e4a2b8f41aac6","user":{"login":"jwolski","id":16902,"avatar_url":"https://avatars.githubusercontent.com/u/16902?v=3","gravatar_id":"","url":"https://api.github.com/users/jwolski","html_url":"https://github.com/jwolski","followers_url":"https://api.github.com/users/jwolski/followers","following_url":"https://api.github.com/users/jwolski/following{/other_user}","gists_url":"https://api.github.com/users/jwolski/gists{/gist_id}","starred_url":"https://api.github.com/users/jwolski/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jwolski/subscriptions","organizations_url":"https://api.github.com/users/jwolski/orgs","repos_url":"https://api.github.com/users/jwolski/repos","events_url":"https://api.github.com/users/jwolski/events{/privacy}","received_events_url":"https://api.github.com/users/jwolski/received_events","type":"User","site_admin":false},"body":"you got it","created_at":"2015-03-20T18:40:40Z","updated_at":"2015-03-20T18:40:40Z","html_url":"https://github.com/uber/ringpop/pull/59#discussion_r26865227","pull_request_url":"https://api.github.com/repos/uber/ringpop/pulls/59","_links":{"self":{"href":"https://api.github.com/repos/uber/ringpop/pulls/comments/26865227"},"html":{"href":"https://github.com/uber/ringpop/pull/59#discussion_r26865227"},"pull_request":{"href":"https://api.github.com/repos/uber/ringpop/pulls/59"}}},"pull_request":{"url":"https://api.github.com/repos/uber/ringpop/pulls/59","id":31537860,"html_url":"https://github.com/uber/ringpop/pull/59","diff_url":"https://github.com/uber/ringpop/pull/59.diff","patch_url":"https://github.com/uber/ringpop/pull/59.patch","issue_url":"https://api.github.com/repos/uber/ringpop/issues/59","number":59,"state":"open","locked":false,"title":"Ping-req uses only ping status from unreachable member to initiate suspect period","user":{"login":"jwolski","id":16902,"avatar_url":"https://avatars.githubusercontent.com/u/16902?v=3","gravatar_id":"","url":"https://api.github.com/users/jwolski","html_url":"https://github.com/jwolski","followers_url":"https://api.github.com/users/jwolski/followers","following_url":"https://api.github.com/users/jwolski/following{/other_user}","gists_url":"https://api.github.com/users/jwolski/gists{/gist_id}","starred_url":"https://api.github.com/users/jwolski/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jwolski/subscriptions","organizations_url":"https://api.github.com/users/jwolski/orgs","repos_url":"https://api.github.com/users/jwolski/repos","events_url":"https://api.github.com/users/jwolski/events{/privacy}","received_events_url":"https://api.github.com/users/jwolski/received_events","type":"User","site_admin":false},"body":"This work is precursor to flap damping. Ping-req's needed to work better.\r\n\r\nWhen nodeA pings nodeB and ping fails, nodeA initiates ping-req to `pingReqSize` random other members: nodeC, nodeD, nodeE. It's each of their responsibilities to ping nodeB on nodeA's behalf. This is known as an indirect ping. When nodeA pings the selected ping-req members (let's say nodeC), one of two things can happen:\r\n\r\n1) nodeA cannot reach ping-req member nodeC\r\n2) nodeA reaches nodeC, nodeC cannot reach nodeB.\r\n\r\nThe first of these two should not count against nodeB. This comes into play in flap damping in the following way. Let's say, nodeB is the flappy one and nodeA damp score for nodeB is nearing the damping threshold. Pings and ping-reqs to nodeB are failing. Every once and a while nodeB responds. It's acting erratically. What makes nodeB not think that nodeA is the flappy one? Well, nodeB has to initiate ping-reqs when pings to nodeA fails. But when nodeB is acting erratically, it's likely that nodeB is at fault for nodeA \"not responding\". If any of the ping-req selected members are able to reach nodeA, then nodeB will never mark nodeA suspect nor will it ever start the suspect period and ultimately never mark the node faulty. Therefore, nodeA should not ever be flappy to nodeB.\r\n\r\n@Raynos @mrhooray @mranney \r\n ","created_at":"2015-03-19T16:03:27Z","updated_at":"2015-03-20T18:40:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0330445291ebc8e2ef53e3406dd21275853163ab","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/uber/ringpop/pulls/59/commits","review_comments_url":"https://api.github.com/repos/uber/ringpop/pulls/59/comments","review_comment_url":"https://api.github.com/repos/uber/ringpop/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uber/ringpop/issues/59/comments","statuses_url":"https://api.github.com/repos/uber/ringpop/statuses/b641eb5f2278eb1e66d7d565568e4a2b8f41aac6","head":{"label":"uber:pingreqerrs","ref":"pingreqerrs","sha":"b641eb5f2278eb1e66d7d565568e4a2b8f41aac6","user":{"login":"uber","id":538264,"avatar_url":"https://avatars.githubusercontent.com/u/538264?v=3","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"repo":{"id":29378455,"name":"ringpop","full_name":"uber/ringpop","owner":{"login":"uber","id":538264,"avatar_url":"https://avatars.githubusercontent.com/u/538264?v=3","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uber/ringpop","description":"Scalable, fault-tolerant application-layer sharding","fork":false,"url":"https://api.github.com/repos/uber/ringpop","forks_url":"https://api.github.com/repos/uber/ringpop/forks","keys_url":"https://api.github.com/repos/uber/ringpop/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uber/ringpop/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uber/ringpop/teams","hooks_url":"https://api.github.com/repos/uber/ringpop/hooks","issue_events_url":"https://api.github.com/repos/uber/ringpop/issues/events{/number}","events_url":"https://api.github.com/repos/uber/ringpop/events","assignees_url":"https://api.github.com/repos/uber/ringpop/assignees{/user}","branches_url":"https://api.github.com/repos/uber/ringpop/branches{/branch}","tags_url":"https://api.github.com/repos/uber/ringpop/tags","blobs_url":"https://api.github.com/repos/uber/ringpop/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uber/ringpop/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uber/ringpop/git/refs{/sha}","trees_url":"https://api.github.com/repos/uber/ringpop/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uber/ringpop/statuses/{sha}","languages_url":"https://api.github.com/repos/uber/ringpop/languages","stargazers_url":"https://api.github.com/repos/uber/ringpop/stargazers","contributors_url":"https://api.github.com/repos/uber/ringpop/contributors","subscribers_url":"https://api.github.com/repos/uber/ringpop/subscribers","subscription_url":"https://api.github.com/repos/uber/ringpop/subscription","commits_url":"https://api.github.com/repos/uber/ringpop/commits{/sha}","git_commits_url":"https://api.github.com/repos/uber/ringpop/git/commits{/sha}","comments_url":"https://api.github.com/repos/uber/ringpop/comments{/number}","issue_comment_url":"https://api.github.com/repos/uber/ringpop/issues/comments{/number}","contents_url":"https://api.github.com/repos/uber/ringpop/contents/{+path}","compare_url":"https://api.github.com/repos/uber/ringpop/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uber/ringpop/merges","archive_url":"https://api.github.com/repos/uber/ringpop/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uber/ringpop/downloads","issues_url":"https://api.github.com/repos/uber/ringpop/issues{/number}","pulls_url":"https://api.github.com/repos/uber/ringpop/pulls{/number}","milestones_url":"https://api.github.com/repos/uber/ringpop/milestones{/number}","notifications_url":"https://api.github.com/repos/uber/ringpop/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uber/ringpop/labels{/name}","releases_url":"https://api.github.com/repos/uber/ringpop/releases{/id}","created_at":"2015-01-17T03:26:35Z","updated_at":"2015-03-20T17:55:53Z","pushed_at":"2015-03-20T03:41:41Z","git_url":"git://github.com/uber/ringpop.git","ssh_url":"git@github.com:uber/ringpop.git","clone_url":"https://github.com/uber/ringpop.git","svn_url":"https://github.com/uber/ringpop","homepage":"","size":2467,"stargazers_count":57,"watchers_count":57,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":16,"forks":1,"open_issues":16,"watchers":57,"default_branch":"master"}},"base":{"label":"uber:master","ref":"master","sha":"ba16a38c33dfb81895ed109963d514c0600b6676","user":{"login":"uber","id":538264,"avatar_url":"https://avatars.githubusercontent.com/u/538264?v=3","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"repo":{"id":29378455,"name":"ringpop","full_name":"uber/ringpop","owner":{"login":"uber","id":538264,"avatar_url":"https://avatars.githubusercontent.com/u/538264?v=3","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uber/ringpop","description":"Scalable, fault-tolerant application-layer sharding","fork":false,"url":"https://api.github.com/repos/uber/ringpop","forks_url":"https://api.github.com/repos/uber/ringpop/forks","keys_url":"https://api.github.com/repos/uber/ringpop/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uber/ringpop/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uber/ringpop/teams","hooks_url":"https://api.github.com/repos/uber/ringpop/hooks","issue_events_url":"https://api.github.com/repos/uber/ringpop/issues/events{/number}","events_url":"https://api.github.com/repos/uber/ringpop/events","assignees_url":"https://api.github.com/repos/uber/ringpop/assignees{/user}","branches_url":"https://api.github.com/repos/uber/ringpop/branches{/branch}","tags_url":"https://api.github.com/repos/uber/ringpop/tags","blobs_url":"https://api.github.com/repos/uber/ringpop/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uber/ringpop/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uber/ringpop/git/refs{/sha}","trees_url":"https://api.github.com/repos/uber/ringpop/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uber/ringpop/statuses/{sha}","languages_url":"https://api.github.com/repos/uber/ringpop/languages","stargazers_url":"https://api.github.com/repos/uber/ringpop/stargazers","contributors_url":"https://api.github.com/repos/uber/ringpop/contributors","subscribers_url":"https://api.github.com/repos/uber/ringpop/subscribers","subscription_url":"https://api.github.com/repos/uber/ringpop/subscription","commits_url":"https://api.github.com/repos/uber/ringpop/commits{/sha}","git_commits_url":"https://api.github.com/repos/uber/ringpop/git/commits{/sha}","comments_url":"https://api.github.com/repos/uber/ringpop/comments{/number}","issue_comment_url":"https://api.github.com/repos/uber/ringpop/issues/comments{/number}","contents_url":"https://api.github.com/repos/uber/ringpop/contents/{+path}","compare_url":"https://api.github.com/repos/uber/ringpop/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uber/ringpop/merges","archive_url":"https://api.github.com/repos/uber/ringpop/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uber/ringpop/downloads","issues_url":"https://api.github.com/repos/uber/ringpop/issues{/number}","pulls_url":"https://api.github.com/repos/uber/ringpop/pulls{/number}","milestones_url":"https://api.github.com/repos/uber/ringpop/milestones{/number}","notifications_url":"https://api.github.com/repos/uber/ringpop/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uber/ringpop/labels{/name}","releases_url":"https://api.github.com/repos/uber/ringpop/releases{/id}","created_at":"2015-01-17T03:26:35Z","updated_at":"2015-03-20T17:55:53Z","pushed_at":"2015-03-20T03:41:41Z","git_url":"git://github.com/uber/ringpop.git","ssh_url":"git@github.com:uber/ringpop.git","clone_url":"https://github.com/uber/ringpop.git","svn_url":"https://github.com/uber/ringpop","homepage":"","size":2467,"stargazers_count":57,"watchers_count":57,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":16,"forks":1,"open_issues":16,"watchers":57,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/uber/ringpop/pulls/59"},"html":{"href":"https://github.com/uber/ringpop/pull/59"},"issue":{"href":"https://api.github.com/repos/uber/ringpop/issues/59"},"comments":{"href":"https://api.github.com/repos/uber/ringpop/issues/59/comments"},"review_comments":{"href":"https://api.github.com/repos/uber/ringpop/pulls/59/comments"},"review_comment":{"href":"https://api.github.com/repos/uber/ringpop/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uber/ringpop/pulls/59/commits"},"statuses":{"href":"https://api.github.com/repos/uber/ringpop/statuses/b641eb5f2278eb1e66d7d565568e4a2b8f41aac6"}}}}