Google Cloud Pub/Sub C++ Client  1.32.1
A C++ Client Library for Google Cloud Pub/Sub
ack_handler.h
Go to the documentation of this file.
1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_PUBSUB_ACK_HANDLER_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_PUBSUB_ACK_HANDLER_H
17 
18 #include "google/cloud/pubsub/version.h"
19 #include "google/cloud/status.h"
20 #include <memory>
21 
22 namespace google {
23 namespace cloud {
24 namespace pubsub {
25 inline namespace GOOGLE_CLOUD_CPP_PUBSUB_NS {
26 
27 /**
28  * Defines the interface to acknowledge and reject messages.
29  *
30  * When applications register a callback to receive Pub/Sub messages the
31  * callback must be able to receive both a `pubsub::Message` and its associated
32  * `pubsub::AckHandler`. Actions on a `pubsub::AckHandler` always affect the
33  * same message received in the callback. Applications cannot create standalone
34  * handlers (except in unit tests via mocks).
35  *
36  * This interface allows applications to acknowledge and reject messages in a
37  * provided to the Cloud Pub/Sub C++ client library. Note that this class is
38  * move-able, to support applications that process messages asynchronously.
39  * However, this class is *not* copy-able, because messages can only be
40  * acknowledged or rejected exactly once.
41  *
42  * @par Thread Safety
43  * This class is *thread compatible*, only one thread should call non-const
44  * member functions of this class at a time. Note that because the non-const
45  * member functions are `&&` overloads the application can only call `ack()` or
46  * `nack()` exactly once, and only one of them.
47  */
48 class AckHandler {
49  public:
50  ~AckHandler();
51 
52  AckHandler(AckHandler&&) = default;
53  AckHandler& operator=(AckHandler&&) = default;
54 
55  /**
56  * Acknowledges the message associated with this handler.
57  *
58  * @par Idempotency
59  * Note that this is not an idempotent operation, and therefore it is never
60  * retried. Furthermore, the service may still resend a message after a
61  * successful `ack()`. Applications developers are reminded that Cloud Pub/Sub
62  * offers "at least once" semantics so they should be prepared to handle
63  * duplicate messages.
64  */
65  void ack() && {
66  auto impl = std::move(impl_);
67  impl->ack();
68  }
69 
70  /**
71  * Rejects the message associated with this handler.
72  *
73  * @par Idempotency
74  * Note that this is not an idempotent operation, and therefore it is never
75  * retried. Furthermore, the service may still resend a message after a
76  * successful `nack()`. Applications developers are reminded that Cloud
77  * Pub/Sub offers "at least once" semantics so they should be prepared to
78  * handle duplicate messages.
79  */
80  void nack() && {
81  auto impl = std::move(impl_);
82  impl->nack();
83  }
84 
85  /// Returns the approximate number of times that Cloud Pub/Sub has attempted
86  /// to deliver the associated message to a subscriber.
87  std::int32_t delivery_attempt() const { return impl_->delivery_attempt(); }
88 
89  /// Allow applications to mock an `AckHandler`.
90  class Impl {
91  public:
92  virtual ~Impl() = 0;
93  /// The implementation for `AckHandler::ack()`
94  virtual void ack() {}
95  /// The implementation for `AckHandler::nack()`
96  virtual void nack() {}
97  /// The implementation for `AckHandler::delivery_attempt()`
98  virtual std::int32_t delivery_attempt() const { return 0; }
99  };
100 
101  /**
102  * Applications may use this constructor in their mocks.
103  */
104  explicit AckHandler(std::unique_ptr<Impl> impl) : impl_(std::move(impl)) {}
105 
106  private:
107  std::unique_ptr<Impl> impl_;
108 };
109 
110 } // namespace GOOGLE_CLOUD_CPP_PUBSUB_NS
111 } // namespace pubsub
112 } // namespace cloud
113 } // namespace google
114 
115 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_PUBSUB_ACK_HANDLER_H