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_POLLING_POLICY_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_POLLING_POLICY_H
17 
18 #include "google/cloud/status.h"
19 #include "google/cloud/version.h"
20 #include <chrono>
21 #include <memory>
22 
23 namespace google {
24 namespace cloud {
25 inline namespace GOOGLE_CLOUD_CPP_NS {
26 
27 /**
28  * Control the Cloud C++ client library behavior with respect to polling on
29  * long running operations.
30  *
31  * Some operations in Cloud services return a `google.longrunning.Operation`
32  * object. As their name implies, these objects represent requests that may take
33  * a long time to complete, in some cases operations may take tens of seconds
34  * or even 30 minutes to complete.
35  *
36  * The Cloud C++ client libraries models these long running operations
37  * as a `google::cloud::future<StatusOr<T>>`, where `T` represents the final
38  * result of the operation. In the background, the library polls the service
39  * until the operation completes (or fails) and then satisfies the future.
40  *
41  * This class defines the interface for policies that control the behavior of
42  * this polling loop.
43  *
44  * @see https://aip.dev/151 for more information on long running operations.
45  */
46 class PollingPolicy {
47  public:
48   virtual ~PollingPolicy() = default;
49 
50   /**
51    * Return a copy of the current policy.
52    *
53    * This function is called at the beginning of the polling loop. Policies that
54    * are based on relative time should restart their timers when this function
55    * is called.
56    */
57   virtual std::unique_ptr<PollingPolicy> clone() const = 0;
58 
59   /**
60    * A callback to indicate that a polling attempt failed.
61    *
62    * This is called when a polling request fails. Note that this callback is not
63    * invoked when the polling request succeeds with "operation not done".
64    *
65    * @return true if the failure should be treated as transient and the polling
66    *     loop should continue.
67    */
68   virtual bool OnFailure(google::cloud::Status const& status) = 0;
69 
70   /**
71    * How long should the polling loop wait before trying again.
72    */
73   virtual std::chrono::milliseconds WaitPeriod() = 0;
74 };
75 
76 template <typename Retry, typename Backoff>
77 class GenericPollingPolicy : public PollingPolicy {
78  public:
GenericPollingPolicy(Retry retry_policy,Backoff backoff_policy)79   GenericPollingPolicy(Retry retry_policy, Backoff backoff_policy)
80       : retry_policy_(std::move(retry_policy)),
81         backoff_policy_(std::move(backoff_policy)) {}
82 
83   //@{
clone()84   std::unique_ptr<PollingPolicy> clone() const override {
85     return std::unique_ptr<PollingPolicy>(new GenericPollingPolicy(*this));
86   }
87 
OnFailure(google::cloud::Status const & status)88   bool OnFailure(google::cloud::Status const& status) override {
89     return retry_policy_.OnFailure(status);
90   }
91 
WaitPeriod()92   std::chrono::milliseconds WaitPeriod() override {
93     return backoff_policy_.OnCompletion();
94   }
95   //@}
96 
97  private:
98   Retry retry_policy_;
99   Backoff backoff_policy_;
100 };
101 
102 }  // namespace GOOGLE_CLOUD_CPP_NS
103 }  // namespace cloud
104 }  // namespace google
105 
106 #endif  // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_POLLING_POLICY_H
107