{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/comments/98254267","pull_request_review_id":18892475,"id":98254267,"diff_hunk":"@@ -779,6 +779,77 @@ def test_context_mgr_failure(self):\n         self.assertEqual(list(batch.messages), [MESSAGE1, MESSAGE2])\n         self.assertEqual(getattr(api, '_topic_published', self), self)\n \n+    def test_message_count_autocommit(self):\n+        \"\"\"Establish that if the batch is assigned to take a maximum\n+        number of messages, that it commits when it reaches that maximum.\n+        \"\"\"\n+        client = _Client(project='PROJECT')\n+        topic = _Topic(name='TOPIC')\n+\n+        # Track commits, but do not perform them.\n+        Batch = self._get_target_class()\n+        with mock.patch.object(Batch, 'commit') as commit:\n+            with self._make_one(topic, client=client, max_messages=5) as batch:\n+                self.assertIsInstance(batch, self._get_target_class())\n+\n+                # Publish four messages and establish that the batch does\n+                # not commit.\n+                for i in range(0, 4):\n+                    batch.publish({\n+                        'attributes': {},\n+                        'data': 'Batch message %d.' % i,\n+                    })\n+                    commit.assert_not_called()\n+\n+                # Publish a fifth message and observe the commit.\n+                batch.publish({\n+                    'attributes': {},\n+                    'data': 'The final call to trigger a commit!',\n+                })\n+                commit.assert_called_once_with()\n+\n+            # There should be a second commit after the context manager\n+            # exits.\n+            self.assertEqual(commit.call_count, 2)\n+\n+    @mock.patch('time.time')\n+    def test_message_time_autocommit(self, mock_time):\n+        \"\"\"Establish that if the batch is sufficiently old, that it commits\n+        the next time it receives a publish.\n+        \"\"\"\n+        client = _Client(project='PROJECT')\n+        topic = _Topic(name='TOPIC')\n+\n+        # Track commits, but do not perform them.\n+        Batch = self._get_target_class()\n+        with mock.patch.object(Batch, 'commit') as commit:\n+            mock_time.return_value = 0.0","path":"pubsub/unit_tests/test_topic.py","position":48,"original_position":48,"commit_id":"eab0b7b04baf7bf0b69c5b4ac644b70673fee723","original_commit_id":"7a6afaa3ac02527bea3e17d4847d639b8b8c805f","user":{"login":"dhermes","id":520669,"avatar_url":"https://avatars.githubusercontent.com/u/520669?v=3","gravatar_id":"","url":"https://api.github.com/users/dhermes","html_url":"https://github.com/dhermes","followers_url":"https://api.github.com/users/dhermes/followers","following_url":"https://api.github.com/users/dhermes/following{/other_user}","gists_url":"https://api.github.com/users/dhermes/gists{/gist_id}","starred_url":"https://api.github.com/users/dhermes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhermes/subscriptions","organizations_url":"https://api.github.com/users/dhermes/orgs","repos_url":"https://api.github.com/users/dhermes/repos","events_url":"https://api.github.com/users/dhermes/events{/privacy}","received_events_url":"https://api.github.com/users/dhermes/received_events","type":"User","site_admin":false},"body":"Yeah that's my bad. But I think my lack of clarity is indicative of something. Suggest instead:\r\n\r\n```python\r\n# The time() that will be set in Batch() constructor\r\nmock_time.return_value = 0.0\r\nbatch = self._make_one(topic, client=client, max_interval=5)\r\nwith batch:\r\n    # do some stuff\r\n    # ...\r\n    # Move time ahead so that this batch is too old.\r\n    mock_time.return_value = 10.0\r\n```\r\n\r\nYou may want to `with batch as batch_ctx` but there is (currently) no reason to since `Batch.__enter__` returns `self`","created_at":"2017-01-27T17:52:31Z","updated_at":"2017-01-27T17:53:32Z","html_url":"https://github.com/GoogleCloudPlatform/google-cloud-python/pull/2966#discussion_r98254267","pull_request_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/2966","_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/comments/98254267"},"html":{"href":"https://github.com/GoogleCloudPlatform/google-cloud-python/pull/2966#discussion_r98254267"},"pull_request":{"href":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/2966"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/2966","id":103394479,"html_url":"https://github.com/GoogleCloudPlatform/google-cloud-python/pull/2966","diff_url":"https://github.com/GoogleCloudPlatform/google-cloud-python/pull/2966.diff","patch_url":"https://github.com/GoogleCloudPlatform/google-cloud-python/pull/2966.patch","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/issues/2966","number":2966,"state":"open","locked":false,"title":"Pubsub batch autocommitting.","user":{"login":"lukesneeringer","id":4346,"avatar_url":"https://avatars.githubusercontent.com/u/4346?v=3","gravatar_id":"","url":"https://api.github.com/users/lukesneeringer","html_url":"https://github.com/lukesneeringer","followers_url":"https://api.github.com/users/lukesneeringer/followers","following_url":"https://api.github.com/users/lukesneeringer/following{/other_user}","gists_url":"https://api.github.com/users/lukesneeringer/gists{/gist_id}","starred_url":"https://api.github.com/users/lukesneeringer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lukesneeringer/subscriptions","organizations_url":"https://api.github.com/users/lukesneeringer/orgs","repos_url":"https://api.github.com/users/lukesneeringer/repos","events_url":"https://api.github.com/users/lukesneeringer/events{/privacy}","received_events_url":"https://api.github.com/users/lukesneeringer/received_events","type":"User","site_admin":false},"body":"This PR adds some functionality to the Batch object:\r\n\r\n  * The ability to specify `max_messages` and have the batch\r\n    automatically call `commit` when the number of messages\r\n    gets that high.\r\n  * The ability to specify `max_interval` and have the batch\r\n    automatically commit when a publish occurs and the batch\r\n    is at least as old as the specified interval.\r\n\r\nThis is one of two changes requested by the PubSub team.","created_at":"2017-01-26T21:36:46Z","updated_at":"2017-01-27T17:53:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b367895037ba2efbe7809419514ece8e46630f15","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/2966/commits","review_comments_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/2966/comments","review_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/issues/2966/comments","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/statuses/eab0b7b04baf7bf0b69c5b4ac644b70673fee723","head":{"label":"lukesneeringer:pubsub-batching","ref":"pubsub-batching","sha":"eab0b7b04baf7bf0b69c5b4ac644b70673fee723","user":{"login":"lukesneeringer","id":4346,"avatar_url":"https://avatars.githubusercontent.com/u/4346?v=3","gravatar_id":"","url":"https://api.github.com/users/lukesneeringer","html_url":"https://github.com/lukesneeringer","followers_url":"https://api.github.com/users/lukesneeringer/followers","following_url":"https://api.github.com/users/lukesneeringer/following{/other_user}","gists_url":"https://api.github.com/users/lukesneeringer/gists{/gist_id}","starred_url":"https://api.github.com/users/lukesneeringer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lukesneeringer/subscriptions","organizations_url":"https://api.github.com/users/lukesneeringer/orgs","repos_url":"https://api.github.com/users/lukesneeringer/repos","events_url":"https://api.github.com/users/lukesneeringer/events{/privacy}","received_events_url":"https://api.github.com/users/lukesneeringer/received_events","type":"User","site_admin":false},"repo":{"id":80044850,"name":"google-cloud-python","full_name":"lukesneeringer/google-cloud-python","owner":{"login":"lukesneeringer","id":4346,"avatar_url":"https://avatars.githubusercontent.com/u/4346?v=3","gravatar_id":"","url":"https://api.github.com/users/lukesneeringer","html_url":"https://github.com/lukesneeringer","followers_url":"https://api.github.com/users/lukesneeringer/followers","following_url":"https://api.github.com/users/lukesneeringer/following{/other_user}","gists_url":"https://api.github.com/users/lukesneeringer/gists{/gist_id}","starred_url":"https://api.github.com/users/lukesneeringer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lukesneeringer/subscriptions","organizations_url":"https://api.github.com/users/lukesneeringer/orgs","repos_url":"https://api.github.com/users/lukesneeringer/repos","events_url":"https://api.github.com/users/lukesneeringer/events{/privacy}","received_events_url":"https://api.github.com/users/lukesneeringer/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lukesneeringer/google-cloud-python","description":"Google Cloud Client Library for Python","fork":true,"url":"https://api.github.com/repos/lukesneeringer/google-cloud-python","forks_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/forks","keys_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/teams","hooks_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/hooks","issue_events_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/issues/events{/number}","events_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/events","assignees_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/assignees{/user}","branches_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/branches{/branch}","tags_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/tags","blobs_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/statuses/{sha}","languages_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/languages","stargazers_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/stargazers","contributors_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/contributors","subscribers_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/subscribers","subscription_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/subscription","commits_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/contents/{+path}","compare_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/merges","archive_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/downloads","issues_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/issues{/number}","pulls_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/pulls{/number}","milestones_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/milestones{/number}","notifications_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/labels{/name}","releases_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/releases{/id}","deployments_url":"https://api.github.com/repos/lukesneeringer/google-cloud-python/deployments","created_at":"2017-01-25T18:39:09Z","updated_at":"2017-01-25T18:39:14Z","pushed_at":"2017-01-27T17:35:23Z","git_url":"git://github.com/lukesneeringer/google-cloud-python.git","ssh_url":"git@github.com:lukesneeringer/google-cloud-python.git","clone_url":"https://github.com/lukesneeringer/google-cloud-python.git","svn_url":"https://github.com/lukesneeringer/google-cloud-python","homepage":"https://googlecloudplatform.github.io/google-cloud-python/","size":111866,"stargazers_count":0,"watchers_count":0,"language":"Python","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":"a70815d30111fc891ce5f847aedc8734b338133f","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":16316451,"name":"google-cloud-python","full_name":"GoogleCloudPlatform/google-cloud-python","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/google-cloud-python","description":"Google Cloud Client Library for Python","fork":false,"url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python","forks_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/forks","keys_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/teams","hooks_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/hooks","issue_events_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/issues/events{/number}","events_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/events","assignees_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/assignees{/user}","branches_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/branches{/branch}","tags_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/tags","blobs_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/statuses/{sha}","languages_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/languages","stargazers_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/stargazers","contributors_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/contributors","subscribers_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/subscribers","subscription_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/subscription","commits_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/contents/{+path}","compare_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/merges","archive_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/downloads","issues_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/issues{/number}","pulls_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls{/number}","milestones_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/milestones{/number}","notifications_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/labels{/name}","releases_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/releases{/id}","deployments_url":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/deployments","created_at":"2014-01-28T15:51:47Z","updated_at":"2017-01-27T13:28:51Z","pushed_at":"2017-01-27T17:35:25Z","git_url":"git://github.com/GoogleCloudPlatform/google-cloud-python.git","ssh_url":"git@github.com:GoogleCloudPlatform/google-cloud-python.git","clone_url":"https://github.com/GoogleCloudPlatform/google-cloud-python.git","svn_url":"https://github.com/GoogleCloudPlatform/google-cloud-python","homepage":"https://googlecloudplatform.github.io/google-cloud-python/","size":112114,"stargazers_count":524,"watchers_count":524,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":273,"mirror_url":null,"open_issues_count":279,"forks":273,"open_issues":279,"watchers":524,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/2966"},"html":{"href":"https://github.com/GoogleCloudPlatform/google-cloud-python/pull/2966"},"issue":{"href":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/issues/2966"},"comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/issues/2966/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/2966/comments"},"review_comment":{"href":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/pulls/2966/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleCloudPlatform/google-cloud-python/statuses/eab0b7b04baf7bf0b69c5b4ac644b70673fee723"}}}}
{"actor":{"display_login":"dhermes"}}