Title: [pubsub] Subscriber.stopAsync().awaitTerminated() doesn't wait for all acks to be sent · Issue #3065 · googleapis/google-cloud-java · GitHub
Open Graph Title: [pubsub] Subscriber.stopAsync().awaitTerminated() doesn't wait for all acks to be sent · Issue #3065 · googleapis/google-cloud-java
X Title: [pubsub] Subscriber.stopAsync().awaitTerminated() doesn't wait for all acks to be sent · Issue #3065 · googleapis/google-cloud-java
Description: In working on a gRPC emulation service for Cloud Pub/Sub, I was trying to validate correct behavior by publishing a series of messages, receiving and acknowleding the exact same set of messages, and then ensuring that no backlog existed ...
Open Graph Description: In working on a gRPC emulation service for Cloud Pub/Sub, I was trying to validate correct behavior by publishing a series of messages, receiving and acknowleding the exact same set of messages, an...
X Description: In working on a gRPC emulation service for Cloud Pub/Sub, I was trying to validate correct behavior by publishing a series of messages, receiving and acknowleding the exact same set of messages, an...
Opengraph URL: https://github.com/googleapis/google-cloud-java/issues/3065
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"[pubsub] Subscriber.stopAsync().awaitTerminated() doesn't wait for all acks to be sent","articleBody":"In working on a gRPC emulation service for Cloud Pub/Sub, I was trying to validate correct behavior by publishing a series of messages, receiving and acknowleding the exact same set of messages, and then ensuring that no backlog existed for the subscription.\r\n\r\nHere's the general test pattern:\r\n```\r\nString messagePrefix = subscriptionProperties.getName() + System.currentTimeMillis() + \"-\";\r\nint messages = 5000;\r\nSet\u003cString\u003e messagesSet = new TreeSet\u003c\u003e();\r\nfor (int i = 0; i \u003c messages; i++) {\r\n messagesSet.add(messagePrefix + i);\r\n}\r\nCountDownLatch countDownLatch = new CountDownLatch(messages);\r\nSet\u003cString\u003e publishedIds = new ConcurrentSkipListSet\u003c\u003e();\r\nMap\u003cString, Integer\u003e receivedIds = new ConcurrentHashMap\u003c\u003e();\r\nfor (String data : messagesSet) {\r\n PubsubMessage message =\r\n PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8(data)).build();\r\n ApiFutures.addCallback(\r\n publisher.publish(message),\r\n new ApiFutureCallback\u003cString\u003e() {\r\n @Override\r\n public void onFailure(Throwable throwable) {\r\n LOGGER.warning(\"Error on Publish \" + throwable.getMessage());\r\n }\r\n\r\n @Override\r\n public void onSuccess(String s) {\r\n publishedIds.add(s);\r\n }\r\n });\r\n}\r\npublisher.shutdown();\r\nassertEquals(messages, publishedIds.size());\r\n\r\nsubscriber =\r\n Subscriber.newBuilder(\r\n ProjectSubscriptionName.of(PROJECT, subscriptionProperties.getName()),\r\n (message, consumer) -\u003e {\r\n consumer.ack();\r\n LOGGER.fine(\"Received and Acknowledging \" + message.getMessageId());\r\n if (!receivedIds.containsKey(message.getMessageId())) {\r\n receivedIds.put(message.getMessageId(), 1);\r\n } else {\r\n int current = receivedIds.get(message.getMessageId());\r\n receivedIds.put(message.getMessageId(), Integer.valueOf(++current));\r\n }\r\n countDownLatch.countDown();\r\n })\r\n //.setChannelProvider(channelProvider)\r\n //.setCredentialsProvider(credentialsProvider)\r\n .build();\r\n\r\npublisher.shutdown();\r\nassertEquals(messages, publishedIds.size());\r\n\r\nsubscriber.startAsync();\r\nLOGGER.info(\"Publisher complete, waiting for 5,000 messages to be received by Subscriber\");\r\ncountDownLatch.await();\r\nLOGGER.info(\"Shutting down Subscriber\");\r\nsubscriber.stopAsync().awaitTerminated();\r\n```\r\n\r\nI executed this test after creating a fresh topic and subscription. My expectation was that after the CountDownLatch reached 0, the Subscriber would shut down and block until all acknowledgements were transmitted.\r\n\r\nIn the client library debug logs, I see the following ack lines, which add up to 5,000 as expected. Interestingly, the final 1,517 acks coming from a thread named *time-limited test*, which is the main thread of my integration test case.\r\n```\r\n2018-03-20 14:10:41.694 [Thread-50] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 78 acks\r\n2018-03-20 14:10:41.693 [Thread-42] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 70 acks\r\n2018-03-20 14:10:41.696 [Thread-46] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 29 acks\r\n2018-03-20 14:10:41.700 [Thread-48] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 100 acks\r\n2018-03-20 14:10:41.695 [Thread-52] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 169 acks\r\n2018-03-20 14:10:41.702 [Thread-44] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 42 acks\r\n2018-03-20 14:10:41.723 [Thread-48] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 281 acks\r\n2018-03-20 14:10:41.729 [Thread-52] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 266 acks\r\n2018-03-20 14:10:41.823 [Thread-50] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 36 acks\r\n2018-03-20 14:10:41.830 [Thread-42] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 75 acks\r\n2018-03-20 14:10:41.832 [Thread-46] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 609 acks\r\n2018-03-20 14:10:41.831 [Thread-48] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 376 acks\r\n2018-03-20 14:10:41.841 [Thread-44] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 186 acks\r\n2018-03-20 14:10:41.841 [Thread-52] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 510 acks\r\n2018-03-20 14:10:41.845 [Thread-50] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 244 acks\r\n2018-03-20 14:10:41.868 [Thread-42] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 412 acks\r\n2018-03-20 14:10:41.887 [Time-limited test] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 106 acks\r\n2018-03-20 14:10:41.888 [Time-limited test] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 496 acks\r\n2018-03-20 14:10:41.892 [Time-limited test] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 379 acks\r\n2018-03-20 14:10:41.894 [Time-limited test] DEBUG com.google.cloud.pubsub.v1.MessageDispatcher : Sending 536 acks\r\n```\r\n\r\nNow, at this point, I can confirm the existence of a backlog by re-running the test but disabling the publisher step. The subscriber should not receive any messages and the test should time out.\r\n\r\nHowever, when I grep for the *Received and Acknowledging * line in my logs, I get a total of *981* rows indicating that those acks that should have been transmitted from the previous run of receiving and acknowledging all 5,000 messages were not received by Cloud Pub/Sub. *981* happens to be the sum of the first three ack batches sent from the *Time-limited test* thread after the subscriber shutdown sequence was invoked.\r\n","author":{"url":"https://github.com/prodonjs","@type":"Person","name":"prodonjs"},"datePublished":"2018-03-20T18:18:26.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/3065/google-cloud-java/issues/3065"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:24e6bfaa-3763-597c-a1fe-7d988c140cbc |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | B00E:2E97A2:B5BB:F5DD:6A4D0223 |
| html-safe-nonce | 0f0cc7d0589f02fc2d91dcbb4841c40f67d28d4badd36370d6e9673823840643 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCMDBFOjJFOTdBMjpCNUJCOkY1REQ6NkE0RDAyMjMiLCJ2aXNpdG9yX2lkIjoiNTI4ODE1MjUxNzYxMTE2MDA5OSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | af6026b76dcceb3b61600c61207744d803d68a1218e4b0046f7c6f713d785ec0 |
| hovercard-subject-tag | issue:306983291 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/googleapis/google-cloud-java/3065/issue_layout |
| twitter:image | https://opengraph.githubassets.com/67b140df98003f395fe9a1997232b70691633facfa68798b9e69eca2c48218a5/googleapis/google-cloud-java/issues/3065 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/67b140df98003f395fe9a1997232b70691633facfa68798b9e69eca2c48218a5/googleapis/google-cloud-java/issues/3065 |
| og:image:alt | In working on a gRPC emulation service for Cloud Pub/Sub, I was trying to validate correct behavior by publishing a series of messages, receiving and acknowleding the exact same set of messages, an... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | prodonjs |
| hostname | github.com |
| expected-hostname | github.com |
| None | 31e4db13a9e20081f2fac78f441659a6576e582bbb15e153f9c7fb6473aa29f5 |
| turbo-cache-control | no-preview |
| go-import | github.com/googleapis/google-cloud-java git https://github.com/googleapis/google-cloud-java.git |
| octolytics-dimension-user_id | 16785467 |
| octolytics-dimension-user_login | googleapis |
| octolytics-dimension-repository_id | 26181278 |
| octolytics-dimension-repository_nwo | googleapis/google-cloud-java |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 26181278 |
| octolytics-dimension-repository_network_root_nwo | googleapis/google-cloud-java |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | fb70bd3c4b2bec429781b65419e912c66e2d5581 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width