You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Give customers access to a new feature in Pub/Sub: exactly once delivery. This
feature guarantee that successfully acknowledged messages are not redelivered,
nor are messages redelivered before their ack deadline expires.
Background
Previously Pub/Sub guaranteed "at least once" delivery, which meant all ack/nack
messages were handled on a best-effort basis. Errors in ack/nack messages were
not exposed to the application, and no retry attempts are made on these RPCs.
Some documents refer to this feature as "Exactly Once Subscribe" (EOS). Others
use "Exactly Once Delivery" (EOD). Sigh.
The proto changes are deceptively small.
First, when a subscription is created it can be configured to use "exactly once
delivery":
Note that all client libraries, including the C++ client libraries do not
use the streaming pull RPC to ack/nack messages. We use the Acknowledge() and ModifyAckDeadline() RPCs. Which unfortunately can accept multiple ack ids,
but cannot return how was each ack id handled. The service has chosen to tunnel
this information via the ErrorInfo. It becomes part of the client library's
job to parse the ErrorInfo and deliver the errors to the application.
The C++ client library provides the following class so applications can ack/nack
messages:
The changes to SubscriberConnection are left as an exercise to the reader.
The futures returned by ack() && and nack() && will be satisfied when:
The ack/nack message is successfully delivered
The ack/nack message fails, and the tunneled error starts with PERMANENT_ERROR. The Status will have StatusCode::kUnknown. The error message will match the
tunneled string, and the ErrorInfo will match the last error info.
The retry attempts are exhausted. The Status will have StatusCode::kUnavailable, and the message will match the last tunneled
string. The ErrorInfo will match the last error info.
The streaming pull is terminated. The error code will be StatusCode::kUnknown. The message will be free form, but a human would be
able to glean what happened.
Breakdown
On streaming pulls, if the stream is configured for exactly once delivery, use the more generous (60 seconds) minimum deadline extension value.
One streaming pulls, if the exactly-once configuration changes, send a deadline extension with the configured value.
Change the pubsub_internal::StreamingBatchSource to return the errors,
ignoring the errors in the existing AckHandler implementation.
If the stream has exactly-once enabled, then use a hard-coded retry policy to retry the ack/nack requests.
If the stream has exactly-once enabled, then use a hard-coded retry policy to update leases.
Parse the ErrorInfo result to implement these retry policies
If the stream does not have exactly-once enabled, then always
succeed, the spec (internal go/cps-eos-client-libraries) says we
should not retry.
Implement a new ExactlyOnceAckHandler::Impl set of classes, these are all in the pubsub_internal namespace.
Refactor AckHandler::Impl to use these classes with errors, but only logs these errors (and ignore failures).
Expose a new ExactlyOnceAckHandler class (and a mock).
Update Subscriber and SubscriberConnection and its mock.
Expose new options to control the minimum deadline extension value
If the application overrides the minimum deadline extension use this value instead.
Implement an example using exactly-once semantics.
Objective
Give customers access to a new feature in Pub/Sub: exactly once delivery. This
feature guarantee that successfully acknowledged messages are not redelivered,
nor are messages redelivered before their ack deadline expires.
Background
Previously Pub/Sub guaranteed "at least once" delivery, which meant all ack/nack
messages were handled on a best-effort basis. Errors in ack/nack messages were
not exposed to the application, and no retry attempts are made on these RPCs.
Some documents refer to this feature as "Exactly Once Subscribe" (EOS). Others
use "Exactly Once Delivery" (EOD). Sigh.
The proto changes are deceptively small.
First, when a subscription is created it can be configured to use "exactly once
delivery":
Second, if you use the streaming API to ack and nack messages you get back
responses with the status of your nack/ack:
Note that all client libraries, including the C++ client libraries do not
use the streaming pull RPC to ack/nack messages. We use the
Acknowledge()andModifyAckDeadline()RPCs. Which unfortunately can accept multiple ack ids,but cannot return how was each ack id handled. The service has chosen to tunnel
this information via the
ErrorInfo. It becomes part of the client library'sjob to parse the
ErrorInfoand deliver the errors to the application.The C++ client library provides the following class so applications can ack/nack
messages:
Proposal
We will introduce a new class to ack/nack messages but with (possible) errors:
Note that
ack() &&andnack() &&now return afuture<Status>. See belowfor how these futures will be satisfied.
To select with
*AckHandlerto use we will changeSubscriber(and
SubscriberConnection) from:to:
The changes to
SubscriberConnectionare left as an exercise to the reader.The futures returned by
ack() &&andnack() &&will be satisfied when:PERMANENT_ERROR. TheStatuswill haveStatusCode::kUnknown. The error message will match thetunneled string, and the
ErrorInfowill match the last error info.Statuswill haveStatusCode::kUnavailable, and the message will match the last tunneledstring. The
ErrorInfowill match the last error info.StatusCode::kUnknown. The message will be free form, but a human would beable to glean what happened.
Breakdown
pubsub_internal::StreamingBatchSourceto return the errors,ignoring the errors in the existing
AckHandlerimplementation.ErrorInforesult to implement these retry policiessucceed, the spec (internal go/cps-eos-client-libraries) says we
should not retry.
ExactlyOnceAckHandler::Implset of classes, these are all in thepubsub_internalnamespace.AckHandler::Implto use these classes with errors, but only logs these errors (and ignore failures).ExactlyOnceAckHandlerclass (and a mock).SubscriberandSubscriberConnectionand its mock.