payload: {"action":"created","comment":{"url":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/comments/283578974","pull_request_review_id":236969821,"id":283578974,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI4MzU3ODk3NA==","diff_hunk":"@@ -0,0 +1,94 @@\n+/*!\n+ * Copyright 2019 Google Inc. All Rights Reserved.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *      http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+import {StatusObject, status} from 'grpc';\n+\n+export interface PullRetryOptions {\n+  maxTimeout: number;\n+}\n+\n+/*!\n+ * retryable status codes\n+ */\n+const RETRY_CODES: status[] = [\n+  status.OK,\n+  status.CANCELLED,\n+  status.UNKNOWN,\n+  status.DEADLINE_EXCEEDED,\n+  status.RESOURCE_EXHAUSTED,\n+  status.ABORTED,\n+  status.INTERNAL,\n+  status.UNAVAILABLE,\n+  status.DATA_LOSS,\n+];\n+\n+/**\n+ * Used to track pull requests and determine if additional requests should be\n+ * made, etc.\n+ *\n+ * @class\n+ * @private\n+ */\n+export class PullRetry {\n+  private failures = 0;\n+  private lastSuccess = Date.now();\n+  private maxTimeout: number;\n+  constructor(options = {} as PullRetryOptions) {\n+    this.maxTimeout = options.maxTimeout;\n+  }\n+  /**\n+   * Generates a timeout that can be used for applying a backoff based on the\n+   * current number of failed requests.\n+   *\n+   * @private\n+   * @returns {number}\n+   */\n+  createTimeout(): number {\n+    if (this.failures === 0) {\n+      return 0;\n+    }\n+    return Math.pow(2, this.failures) * 1000 + Math.floor(Math.random() * 1000);\n+  }\n+  /**\n+   * Determines if a request status should be retried.\n+   *\n+   * Deadlines behave kind of unexpectedly on streams, rather than using it as\n+   * an indicator of when to give up trying to connect, it actually dictates\n+   * how long the stream should stay open. Because of this, it is virtually\n+   * impossible to determine whether or not a deadline error is the result of\n+   * the server closing the stream or if we timed out waiting for a connection.\n+   * Typically we might use something like grpc's waitForReady, but there is an\n+   * open issue that prevents this from working with channel pooling.\n+   *\n+   * @private\n+   * @param {object} status The request status.\n+   * @returns {boolean}\n+   */\n+  retry(s: StatusObject): boolean {\n+    if (s.code === status.OK || s.code === status.DEADLINE_EXCEEDED) {","path":"src/pull-retry.ts","position":81,"original_position":81,"commit_id":"90e1ba72fbaf9dda6838be90a5835e9ebedcedf6","original_commit_id":"90e1ba72fbaf9dda6838be90a5835e9ebedcedf6","user":{"login":"callmehiphop","id":1707267,"node_id":"MDQ6VXNlcjE3MDcyNjc=","avatar_url":"https://avatars3.githubusercontent.com/u/1707267?v=4","gravatar_id":"","url":"https://api.github.com/users/callmehiphop","html_url":"https://github.com/callmehiphop","followers_url":"https://api.github.com/users/callmehiphop/followers","following_url":"https://api.github.com/users/callmehiphop/following{/other_user}","gists_url":"https://api.github.com/users/callmehiphop/gists{/gist_id}","starred_url":"https://api.github.com/users/callmehiphop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/callmehiphop/subscriptions","organizations_url":"https://api.github.com/users/callmehiphop/orgs","repos_url":"https://api.github.com/users/callmehiphop/repos","events_url":"https://api.github.com/users/callmehiphop/events{/privacy}","received_events_url":"https://api.github.com/users/callmehiphop/received_events","type":"User","site_admin":false},"body":"I actually wrote a little blurb specifically about why we basically ignore deadline errors in the JSDoc description for this method. Deadline behavior changes a bit when applied to a stream, instead of being a timeout it actually dictates how long the stream should stay open for.\r\n\r\n","created_at":"2019-05-13T23:46:48Z","updated_at":"2019-05-13T23:46:48Z","html_url":"https://github.com/googleapis/nodejs-pubsub/pull/607#discussion_r283578974","pull_request_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/607","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/comments/283578974"},"html":{"href":"https://github.com/googleapis/nodejs-pubsub/pull/607#discussion_r283578974"},"pull_request":{"href":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/607"}},"in_reply_to_id":283561150},"pull_request":{"url":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/607","id":278252329,"node_id":"MDExOlB1bGxSZXF1ZXN0Mjc4MjUyMzI5","html_url":"https://github.com/googleapis/nodejs-pubsub/pull/607","diff_url":"https://github.com/googleapis/nodejs-pubsub/pull/607.diff","patch_url":"https://github.com/googleapis/nodejs-pubsub/pull/607.patch","issue_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/issues/607","number":607,"state":"open","locked":false,"title":"refactor(subscriber): message stream retry logic","user":{"login":"callmehiphop","id":1707267,"node_id":"MDQ6VXNlcjE3MDcyNjc=","avatar_url":"https://avatars3.githubusercontent.com/u/1707267?v=4","gravatar_id":"","url":"https://api.github.com/users/callmehiphop","html_url":"https://github.com/callmehiphop","followers_url":"https://api.github.com/users/callmehiphop/followers","following_url":"https://api.github.com/users/callmehiphop/following{/other_user}","gists_url":"https://api.github.com/users/callmehiphop/gists{/gist_id}","starred_url":"https://api.github.com/users/callmehiphop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/callmehiphop/subscriptions","organizations_url":"https://api.github.com/users/callmehiphop/orgs","repos_url":"https://api.github.com/users/callmehiphop/repos","events_url":"https://api.github.com/users/callmehiphop/events{/privacy}","received_events_url":"https://api.github.com/users/callmehiphop/received_events","type":"User","site_admin":false},"body":"Fixes #550\r\nCloses #594\r\n\r\n- [ ] Tests and linter pass\r\n- [ ] Code coverage does not decrease (if any source code was changed)\r\n- [x] Appropriate docs were updated (if necessary)\r\n","created_at":"2019-05-13T12:29:46Z","updated_at":"2019-05-13T23:46:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f9735e6877f1672388fb5778cf07c3e95fb30e47","assignee":null,"assignees":[],"requested_reviewers":[{"login":"ajaaym","id":34161822,"node_id":"MDQ6VXNlcjM0MTYxODIy","avatar_url":"https://avatars0.githubusercontent.com/u/34161822?v=4","gravatar_id":"","url":"https://api.github.com/users/ajaaym","html_url":"https://github.com/ajaaym","followers_url":"https://api.github.com/users/ajaaym/followers","following_url":"https://api.github.com/users/ajaaym/following{/other_user}","gists_url":"https://api.github.com/users/ajaaym/gists{/gist_id}","starred_url":"https://api.github.com/users/ajaaym/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ajaaym/subscriptions","organizations_url":"https://api.github.com/users/ajaaym/orgs","repos_url":"https://api.github.com/users/ajaaym/repos","events_url":"https://api.github.com/users/ajaaym/events{/privacy}","received_events_url":"https://api.github.com/users/ajaaym/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":977115753,"node_id":"MDU6TGFiZWw5NzcxMTU3NTM=","url":"https://api.github.com/repos/googleapis/nodejs-pubsub/labels/cla:%20yes","name":"cla: yes","color":"0B7601","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/607/commits","review_comments_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/607/comments","review_comment_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/comments{/number}","comments_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/issues/607/comments","statuses_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/statuses/90e1ba72fbaf9dda6838be90a5835e9ebedcedf6","head":{"label":"callmehiphop:dg--stream-retries","ref":"dg--stream-retries","sha":"90e1ba72fbaf9dda6838be90a5835e9ebedcedf6","user":{"login":"callmehiphop","id":1707267,"node_id":"MDQ6VXNlcjE3MDcyNjc=","avatar_url":"https://avatars3.githubusercontent.com/u/1707267?v=4","gravatar_id":"","url":"https://api.github.com/users/callmehiphop","html_url":"https://github.com/callmehiphop","followers_url":"https://api.github.com/users/callmehiphop/followers","following_url":"https://api.github.com/users/callmehiphop/following{/other_user}","gists_url":"https://api.github.com/users/callmehiphop/gists{/gist_id}","starred_url":"https://api.github.com/users/callmehiphop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/callmehiphop/subscriptions","organizations_url":"https://api.github.com/users/callmehiphop/orgs","repos_url":"https://api.github.com/users/callmehiphop/repos","events_url":"https://api.github.com/users/callmehiphop/events{/privacy}","received_events_url":"https://api.github.com/users/callmehiphop/received_events","type":"User","site_admin":false},"repo":{"id":113098752,"node_id":"MDEwOlJlcG9zaXRvcnkxMTMwOTg3NTI=","name":"nodejs-pubsub","full_name":"callmehiphop/nodejs-pubsub","private":false,"owner":{"login":"callmehiphop","id":1707267,"node_id":"MDQ6VXNlcjE3MDcyNjc=","avatar_url":"https://avatars3.githubusercontent.com/u/1707267?v=4","gravatar_id":"","url":"https://api.github.com/users/callmehiphop","html_url":"https://github.com/callmehiphop","followers_url":"https://api.github.com/users/callmehiphop/followers","following_url":"https://api.github.com/users/callmehiphop/following{/other_user}","gists_url":"https://api.github.com/users/callmehiphop/gists{/gist_id}","starred_url":"https://api.github.com/users/callmehiphop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/callmehiphop/subscriptions","organizations_url":"https://api.github.com/users/callmehiphop/orgs","repos_url":"https://api.github.com/users/callmehiphop/repos","events_url":"https://api.github.com/users/callmehiphop/events{/privacy}","received_events_url":"https://api.github.com/users/callmehiphop/received_events","type":"User","site_admin":false},"html_url":"https://github.com/callmehiphop/nodejs-pubsub","description":"Node.js client for Google Cloud Pub/Sub: Ingest event streams from anywhere, at any scale, for simple, reliable, real-time stream analytics.","fork":true,"url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub","forks_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/forks","keys_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/keys{/key_id}","collaborators_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/teams","hooks_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/hooks","issue_events_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/issues/events{/number}","events_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/events","assignees_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/assignees{/user}","branches_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/branches{/branch}","tags_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/tags","blobs_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/git/refs{/sha}","trees_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/git/trees{/sha}","statuses_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/statuses/{sha}","languages_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/languages","stargazers_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/stargazers","contributors_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/contributors","subscribers_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/subscribers","subscription_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/subscription","commits_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/commits{/sha}","git_commits_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/git/commits{/sha}","comments_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/comments{/number}","issue_comment_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/issues/comments{/number}","contents_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/contents/{+path}","compare_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/compare/{base}...{head}","merges_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/merges","archive_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/downloads","issues_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/issues{/number}","pulls_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/pulls{/number}","milestones_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/milestones{/number}","notifications_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/labels{/name}","releases_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/releases{/id}","deployments_url":"https://api.github.com/repos/callmehiphop/nodejs-pubsub/deployments","created_at":"2017-12-04T21:46:37Z","updated_at":"2017-12-04T21:46:38Z","pushed_at":"2019-05-13T12:27:51Z","git_url":"git://github.com/callmehiphop/nodejs-pubsub.git","ssh_url":"git@github.com:callmehiphop/nodejs-pubsub.git","clone_url":"https://github.com/callmehiphop/nodejs-pubsub.git","svn_url":"https://github.com/callmehiphop/nodejs-pubsub","homepage":"https://cloud.google.com/pubsub/","size":2817,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"googleapis:master","ref":"master","sha":"6415e7c5f16da715ef1af8ca67c71216845e0328","user":{"login":"googleapis","id":16785467,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2Nzg1NDY3","avatar_url":"https://avatars3.githubusercontent.com/u/16785467?v=4","gravatar_id":"","url":"https://api.github.com/users/googleapis","html_url":"https://github.com/googleapis","followers_url":"https://api.github.com/users/googleapis/followers","following_url":"https://api.github.com/users/googleapis/following{/other_user}","gists_url":"https://api.github.com/users/googleapis/gists{/gist_id}","starred_url":"https://api.github.com/users/googleapis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/googleapis/subscriptions","organizations_url":"https://api.github.com/users/googleapis/orgs","repos_url":"https://api.github.com/users/googleapis/repos","events_url":"https://api.github.com/users/googleapis/events{/privacy}","received_events_url":"https://api.github.com/users/googleapis/received_events","type":"Organization","site_admin":false},"repo":{"id":98464783,"node_id":"MDEwOlJlcG9zaXRvcnk5ODQ2NDc4Mw==","name":"nodejs-pubsub","full_name":"googleapis/nodejs-pubsub","private":false,"owner":{"login":"googleapis","id":16785467,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2Nzg1NDY3","avatar_url":"https://avatars3.githubusercontent.com/u/16785467?v=4","gravatar_id":"","url":"https://api.github.com/users/googleapis","html_url":"https://github.com/googleapis","followers_url":"https://api.github.com/users/googleapis/followers","following_url":"https://api.github.com/users/googleapis/following{/other_user}","gists_url":"https://api.github.com/users/googleapis/gists{/gist_id}","starred_url":"https://api.github.com/users/googleapis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/googleapis/subscriptions","organizations_url":"https://api.github.com/users/googleapis/orgs","repos_url":"https://api.github.com/users/googleapis/repos","events_url":"https://api.github.com/users/googleapis/events{/privacy}","received_events_url":"https://api.github.com/users/googleapis/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/googleapis/nodejs-pubsub","description":"Node.js client for Google Cloud Pub/Sub: Ingest event streams from anywhere, at any scale, for simple, reliable, real-time stream analytics.","fork":false,"url":"https://api.github.com/repos/googleapis/nodejs-pubsub","forks_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/forks","keys_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/keys{/key_id}","collaborators_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/teams","hooks_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/hooks","issue_events_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/issues/events{/number}","events_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/events","assignees_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/assignees{/user}","branches_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/branches{/branch}","tags_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/tags","blobs_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/git/refs{/sha}","trees_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/git/trees{/sha}","statuses_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/statuses/{sha}","languages_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/languages","stargazers_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/stargazers","contributors_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/contributors","subscribers_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/subscribers","subscription_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/subscription","commits_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/commits{/sha}","git_commits_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/git/commits{/sha}","comments_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/comments{/number}","issue_comment_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/issues/comments{/number}","contents_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/contents/{+path}","compare_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/compare/{base}...{head}","merges_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/merges","archive_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/downloads","issues_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/issues{/number}","pulls_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls{/number}","milestones_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/milestones{/number}","notifications_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/labels{/name}","releases_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/releases{/id}","deployments_url":"https://api.github.com/repos/googleapis/nodejs-pubsub/deployments","created_at":"2017-07-26T20:50:19Z","updated_at":"2019-05-11T14:16:17Z","pushed_at":"2019-05-13T16:34:31Z","git_url":"git://github.com/googleapis/nodejs-pubsub.git","ssh_url":"git@github.com:googleapis/nodejs-pubsub.git","clone_url":"https://github.com/googleapis/nodejs-pubsub.git","svn_url":"https://github.com/googleapis/nodejs-pubsub","homepage":"https://cloud.google.com/pubsub/","size":2803,"stargazers_count":147,"watchers_count":147,"language":"TypeScript","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":111,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":15,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":111,"open_issues":15,"watchers":147,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/607"},"html":{"href":"https://github.com/googleapis/nodejs-pubsub/pull/607"},"issue":{"href":"https://api.github.com/repos/googleapis/nodejs-pubsub/issues/607"},"comments":{"href":"https://api.github.com/repos/googleapis/nodejs-pubsub/issues/607/comments"},"review_comments":{"href":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/607/comments"},"review_comment":{"href":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/googleapis/nodejs-pubsub/pulls/607/commits"},"statuses":{"href":"https://api.github.com/repos/googleapis/nodejs-pubsub/statuses/90e1ba72fbaf9dda6838be90a5835e9ebedcedf6"}},"author_association":"MEMBER"}}
other: {"actor":{"display_login":"callmehiphop"}}