{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/comments/46201138","id":46201138,"diff_hunk":"@@ -120,95 +179,119 @@ public void sendMessage(RequestT message) {\n       Preconditions.checkState(callDelegate != null, \"Not started\");\n       callDelegate.sendMessage(message);\n     }\n-\n   }\n \n-  // We can't do a newCall on a closed delegate.  This will ensure that refreshes don't \n-  // allow a closed delegate to perform a newCall.  Once closed is called, all existing\n-  // calls will complete before the delegate shuts down.\n-  private final AtomicInteger closingAsynchronously = new AtomicInteger(0);\n-\n-  private final long maxRefreshTime;\n+  private final long maxRefreshMs;\n   private final Factory factory;\n+  private final String authority;\n+\n+  private ChannelWrapper delegate;\n+\n+  /**\n+   * @param maxRefreshMs  The maximum amount of time before the channel should be discarded in ms.\n+   * @param connectionFactory Creates a Channel and a way to close it.\n+   * @throws IOException on channel creation. The SSLContext creation would be the likely culprit.\n+   */\n+  public ReconnectingChannel(long maxRefreshMs, Factory connectionFactory) throws IOException {\n+    this(maxRefreshMs, connectionFactory,\n+        Executors.newScheduledThreadPool(\n+            2,\n+            new ThreadFactoryBuilder()\n+                .setNameFormat(\"reconnection-async-close-%s\")\n+                .setDaemon(true)\n+                .build()));\n+  }\n \n-  // nextRefresh and delegate need to be protected by delegateLock.\n-  private long nextRefresh;\n-  private Channel delegate;\n-\n-  public ReconnectingChannel(\n-      long maxRefreshTime,\n-      Factory connectionFactory) throws IOException {\n-    Preconditions.checkArgument(maxRefreshTime >= 0L, \"maxRefreshTime cannot be less than 0.\");\n-    this.maxRefreshTime = maxRefreshTime;\n-    this.delegate = connectionFactory.createChannel();\n-    this.nextRefresh = calculateNewRefreshTime();\n+  /**\n+   * @param maxRefreshMs  The maximum amount of time before the channel should be discarded in ms.\n+   * @param connectionFactory Creates a Channel and a way to close it.\n+   * @param executorService Manages the creation of new Channels and closing ofthe old ones.\n+   * @throws IOException on channel creation. The SSLContext creation would be the likely culprit.\n+   */\n+  @VisibleForTesting\n+  ReconnectingChannel(\n+      long maxRefreshMs,\n+      Factory connectionFactory,\n+      ScheduledExecutorService executorService) throws IOException {\n+    Preconditions.checkArgument(maxRefreshMs >= 0L, \"maxRefreshTime cannot be less than 0.\");","path":"bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/io/ReconnectingChannel.java","position":236,"original_position":236,"commit_id":"35d08a4883c5aefce21d23fecc0e323193933811","original_commit_id":"35d08a4883c5aefce21d23fecc0e323193933811","user":{"login":"gamorris","id":15039361,"avatar_url":"https://avatars.githubusercontent.com/u/15039361?v=3","gravatar_id":"","url":"https://api.github.com/users/gamorris","html_url":"https://github.com/gamorris","followers_url":"https://api.github.com/users/gamorris/followers","following_url":"https://api.github.com/users/gamorris/following{/other_user}","gists_url":"https://api.github.com/users/gamorris/gists{/gist_id}","starred_url":"https://api.github.com/users/gamorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gamorris/subscriptions","organizations_url":"https://api.github.com/users/gamorris/orgs","repos_url":"https://api.github.com/users/gamorris/repos","events_url":"https://api.github.com/users/gamorris/events{/privacy}","received_events_url":"https://api.github.com/users/gamorris/received_events","type":"User","site_admin":false},"body":"maxRefreshTime -> `maxRefreshMs`","created_at":"2015-11-30T20:48:12Z","updated_at":"2015-11-30T20:48:12Z","html_url":"https://github.com/GoogleCloudPlatform/cloud-bigtable-client/pull/583#discussion_r46201138","pull_request_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/583","_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/comments/46201138"},"html":{"href":"https://github.com/GoogleCloudPlatform/cloud-bigtable-client/pull/583#discussion_r46201138"},"pull_request":{"href":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/583"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/583","id":51829797,"html_url":"https://github.com/GoogleCloudPlatform/cloud-bigtable-client/pull/583","diff_url":"https://github.com/GoogleCloudPlatform/cloud-bigtable-client/pull/583.diff","patch_url":"https://github.com/GoogleCloudPlatform/cloud-bigtable-client/pull/583.patch","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/issues/583","number":583,"state":"open","locked":false,"title":"Shortening the locked portions of ReconnectingChannel.","user":{"login":"sduskis","id":99305,"avatar_url":"https://avatars.githubusercontent.com/u/99305?v=3","gravatar_id":"","url":"https://api.github.com/users/sduskis","html_url":"https://github.com/sduskis","followers_url":"https://api.github.com/users/sduskis/followers","following_url":"https://api.github.com/users/sduskis/following{/other_user}","gists_url":"https://api.github.com/users/sduskis/gists{/gist_id}","starred_url":"https://api.github.com/users/sduskis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sduskis/subscriptions","organizations_url":"https://api.github.com/users/sduskis/orgs","repos_url":"https://api.github.com/users/sduskis/repos","events_url":"https://api.github.com/users/sduskis/events{/privacy}","received_events_url":"https://api.github.com/users/sduskis/received_events","type":"User","site_admin":false},"body":"This PR reduces the amount of logic that's synchronized in ReconnectingChannel, while maintaining the same level of thread safety.  Refreshing logic is now moved into a scheduled task rather than a check per newCall.\r\n\r\nMicrobenchmarks show that the core logic of ReconnectingChannel is a few microseconds faster in high concurrency situations (with mock channels and clientCall objects).","created_at":"2015-11-25T18:23:12Z","updated_at":"2015-11-30T20:48:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2577a3a9cd969d9c77b33439991903a928c0f8f6","assignee":{"login":"gamorris","id":15039361,"avatar_url":"https://avatars.githubusercontent.com/u/15039361?v=3","gravatar_id":"","url":"https://api.github.com/users/gamorris","html_url":"https://github.com/gamorris","followers_url":"https://api.github.com/users/gamorris/followers","following_url":"https://api.github.com/users/gamorris/following{/other_user}","gists_url":"https://api.github.com/users/gamorris/gists{/gist_id}","starred_url":"https://api.github.com/users/gamorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gamorris/subscriptions","organizations_url":"https://api.github.com/users/gamorris/orgs","repos_url":"https://api.github.com/users/gamorris/repos","events_url":"https://api.github.com/users/gamorris/events{/privacy}","received_events_url":"https://api.github.com/users/gamorris/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/583/commits","review_comments_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/583/comments","review_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/issues/583/comments","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/statuses/35d08a4883c5aefce21d23fecc0e323193933811","head":{"label":"sduskis:reconnect_channel_count","ref":"reconnect_channel_count","sha":"35d08a4883c5aefce21d23fecc0e323193933811","user":{"login":"sduskis","id":99305,"avatar_url":"https://avatars.githubusercontent.com/u/99305?v=3","gravatar_id":"","url":"https://api.github.com/users/sduskis","html_url":"https://github.com/sduskis","followers_url":"https://api.github.com/users/sduskis/followers","following_url":"https://api.github.com/users/sduskis/following{/other_user}","gists_url":"https://api.github.com/users/sduskis/gists{/gist_id}","starred_url":"https://api.github.com/users/sduskis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sduskis/subscriptions","organizations_url":"https://api.github.com/users/sduskis/orgs","repos_url":"https://api.github.com/users/sduskis/repos","events_url":"https://api.github.com/users/sduskis/events{/privacy}","received_events_url":"https://api.github.com/users/sduskis/received_events","type":"User","site_admin":false},"repo":{"id":35497990,"name":"cloud-bigtable-client","full_name":"sduskis/cloud-bigtable-client","owner":{"login":"sduskis","id":99305,"avatar_url":"https://avatars.githubusercontent.com/u/99305?v=3","gravatar_id":"","url":"https://api.github.com/users/sduskis","html_url":"https://github.com/sduskis","followers_url":"https://api.github.com/users/sduskis/followers","following_url":"https://api.github.com/users/sduskis/following{/other_user}","gists_url":"https://api.github.com/users/sduskis/gists{/gist_id}","starred_url":"https://api.github.com/users/sduskis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sduskis/subscriptions","organizations_url":"https://api.github.com/users/sduskis/orgs","repos_url":"https://api.github.com/users/sduskis/repos","events_url":"https://api.github.com/users/sduskis/events{/privacy}","received_events_url":"https://api.github.com/users/sduskis/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sduskis/cloud-bigtable-client","description":"HBase client extension to access Google Cloud Bigtable","fork":true,"url":"https://api.github.com/repos/sduskis/cloud-bigtable-client","forks_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/forks","keys_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/teams","hooks_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/hooks","issue_events_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/issues/events{/number}","events_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/events","assignees_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/assignees{/user}","branches_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/branches{/branch}","tags_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/tags","blobs_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/git/refs{/sha}","trees_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/statuses/{sha}","languages_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/languages","stargazers_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/stargazers","contributors_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/contributors","subscribers_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/subscribers","subscription_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/subscription","commits_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/commits{/sha}","git_commits_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/git/commits{/sha}","comments_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/comments{/number}","issue_comment_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/issues/comments{/number}","contents_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/contents/{+path}","compare_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/merges","archive_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/downloads","issues_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/issues{/number}","pulls_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/pulls{/number}","milestones_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/milestones{/number}","notifications_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/labels{/name}","releases_url":"https://api.github.com/repos/sduskis/cloud-bigtable-client/releases{/id}","created_at":"2015-05-12T15:56:54Z","updated_at":"2015-05-12T15:58:10Z","pushed_at":"2015-11-30T20:31:35Z","git_url":"git://github.com/sduskis/cloud-bigtable-client.git","ssh_url":"git@github.com:sduskis/cloud-bigtable-client.git","clone_url":"https://github.com/sduskis/cloud-bigtable-client.git","svn_url":"https://github.com/sduskis/cloud-bigtable-client","homepage":"","size":4663,"stargazers_count":0,"watchers_count":0,"language":"Java","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":"GoogleCloudPlatform:master","ref":"master","sha":"e5e0e224353f5648af08aa633b6e15ef5a0f8356","user":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"repo":{"id":18442381,"name":"cloud-bigtable-client","full_name":"GoogleCloudPlatform/cloud-bigtable-client","owner":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GoogleCloudPlatform/cloud-bigtable-client","description":"HBase client extension to access Google Cloud Bigtable","fork":false,"url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client","forks_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/forks","keys_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/teams","hooks_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/hooks","issue_events_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/issues/events{/number}","events_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/events","assignees_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/assignees{/user}","branches_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/branches{/branch}","tags_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/tags","blobs_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/git/refs{/sha}","trees_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/statuses/{sha}","languages_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/languages","stargazers_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/stargazers","contributors_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/contributors","subscribers_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/subscribers","subscription_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/subscription","commits_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/commits{/sha}","git_commits_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/git/commits{/sha}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/comments{/number}","issue_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/issues/comments{/number}","contents_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/contents/{+path}","compare_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/merges","archive_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/downloads","issues_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/issues{/number}","pulls_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls{/number}","milestones_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/milestones{/number}","notifications_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/labels{/name}","releases_url":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/releases{/id}","created_at":"2014-04-04T14:54:35Z","updated_at":"2015-11-26T07:59:12Z","pushed_at":"2015-11-30T20:41:45Z","git_url":"git://github.com/GoogleCloudPlatform/cloud-bigtable-client.git","ssh_url":"git@github.com:GoogleCloudPlatform/cloud-bigtable-client.git","clone_url":"https://github.com/GoogleCloudPlatform/cloud-bigtable-client.git","svn_url":"https://github.com/GoogleCloudPlatform/cloud-bigtable-client","homepage":"","size":11477,"stargazers_count":39,"watchers_count":39,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":26,"mirror_url":null,"open_issues_count":15,"forks":26,"open_issues":15,"watchers":39,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/583"},"html":{"href":"https://github.com/GoogleCloudPlatform/cloud-bigtable-client/pull/583"},"issue":{"href":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/issues/583"},"comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/issues/583/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/583/comments"},"review_comment":{"href":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/pulls/583/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleCloudPlatform/cloud-bigtable-client/statuses/35d08a4883c5aefce21d23fecc0e323193933811"}}}}