From f583e3f78c597bc4d28198a4fdb834d9b905b018 Mon Sep 17 00:00:00 2001 From: Carlos O'Ryan Date: Thu, 6 Jul 2023 13:53:43 -0400 Subject: [PATCH] docs(pubsub): document `RetryPolicy` interface (#12030) --- google/cloud/pubsub/retry_policy.h | 134 ++++++++++++++++++++++++++--- 1 file changed, 123 insertions(+), 11 deletions(-) diff --git a/google/cloud/pubsub/retry_policy.h b/google/cloud/pubsub/retry_policy.h index 59814d218f625..994666dca21e2 100644 --- a/google/cloud/pubsub/retry_policy.h +++ b/google/cloud/pubsub/retry_policy.h @@ -18,6 +18,8 @@ #include "google/cloud/pubsub/version.h" #include "google/cloud/internal/retry_policy_impl.h" #include "google/cloud/status.h" +#include +#include namespace google { namespace cloud { @@ -40,19 +42,129 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END namespace pubsub { GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN -/// The base class for retry policies. -using RetryPolicy = ::google::cloud::internal::TraitBasedRetryPolicy< - pubsub_internal::RetryTraits>; +/// The base class for the Pub/Sub library retry policies. +class RetryPolicy : public google::cloud::RetryPolicy { + public: + /// Creates a new instance of the policy, reset to the initial state. + virtual std::unique_ptr clone() const = 0; +}; + +/** + * A retry policy based on counting errors. + * + * This policy stops retrying if: + * - An RPC returns a non-transient error. + * - More than a prescribed number of transient failures is detected. + * + * In this class the following status codes are treated as transient errors: + * - [`kAborted`](@ref google::cloud::StatusCode) + * - [`kInternal`](@ref google::cloud::StatusCode) + * - [`kUnavailable`](@ref google::cloud::StatusCode) + * - [`kResourceExhausted`](@ref google::cloud::StatusCode) + */ +class LimitedErrorCountRetryPolicy : public RetryPolicy { + public: + /** + * Create an instance that tolerates up to @p maximum_failures transient + * errors. + * + * @note Disable the retry loop by providing an instance of this policy with + * @p maximum_failures == 0. + */ + explicit LimitedErrorCountRetryPolicy(int maximum_failures) + : impl_(maximum_failures) {} + + LimitedErrorCountRetryPolicy(LimitedErrorCountRetryPolicy&& rhs) noexcept + : LimitedErrorCountRetryPolicy(rhs.maximum_failures()) {} + LimitedErrorCountRetryPolicy(LimitedErrorCountRetryPolicy const& rhs) noexcept + : LimitedErrorCountRetryPolicy(rhs.maximum_failures()) {} + + int maximum_failures() const { return impl_.maximum_failures(); } + + bool OnFailure(Status const& s) override { return impl_.OnFailure(s); } + bool IsExhausted() const override { return impl_.IsExhausted(); } + bool IsPermanentFailure(Status const& s) const override { + return impl_.IsPermanentFailure(s); + } + std::unique_ptr clone() const override { + return std::make_unique( + impl_.maximum_failures()); + } + + // This is provided only for backwards compatibility. + using BaseType = RetryPolicy; + + private: + google::cloud::internal::LimitedErrorCountRetryPolicy< + pubsub_internal::RetryTraits> + impl_; +}; + +/** + * A retry policy based on elapsed time. + * + * This policy stops retrying if: + * - An RPC returns a non-transient error. + * - The elapsed time in the retry loop exceeds a prescribed duration. + * + * In this class the following status codes are treated as transient errors: + * - [`kAborted`](@ref google::cloud::StatusCode) + * - [`kInternal`](@ref google::cloud::StatusCode) + * - [`kUnavailable`](@ref google::cloud::StatusCode) + * - [`kResourceExhausted`](@ref google::cloud::StatusCode) + */ +class LimitedTimeRetryPolicy : public RetryPolicy { + public: + /** + * Constructor given a `std::chrono::duration<>` object. + * + * @tparam DurationRep a placeholder to match the `Rep` tparam for + * @p maximum_duration's type. The semantics of this template parameter + * are documented in `std::chrono::duration<>`. In brief, the underlying + * arithmetic type used to store the number of ticks. For our purposes it + * is simply a formal parameter. + * @tparam DurationPeriod a placeholder to match the `Period` tparam for + * @p maximum_duration's type. The semantics of this template parameter + * are documented in `std::chrono::duration<>`. In brief, the length of + * the tick in seconds, expressed as a `std::ratio<>`. For our purposes it + * is simply a formal parameter. + * @param maximum_duration the maximum time allowed before the policy expires, + * while the application can express this time in any units they desire, + * the class truncates to milliseconds. + * + * @see https://en.cppreference.com/w/cpp/chrono/duration for more details + * about `std::chrono::duration`. + */ + template + explicit LimitedTimeRetryPolicy( + std::chrono::duration maximum_duration) + : impl_(maximum_duration) {} -/// A retry policy that limits based on time. -using LimitedTimeRetryPolicy = - ::google::cloud::internal::LimitedTimeRetryPolicy< - pubsub_internal::RetryTraits>; + LimitedTimeRetryPolicy(LimitedTimeRetryPolicy&& rhs) noexcept + : LimitedTimeRetryPolicy(rhs.maximum_duration()) {} + LimitedTimeRetryPolicy(LimitedTimeRetryPolicy const& rhs) noexcept + : LimitedTimeRetryPolicy(rhs.maximum_duration()) {} -/// A retry policy that limits the number of times a request can fail. -using LimitedErrorCountRetryPolicy = - google::cloud::internal::LimitedErrorCountRetryPolicy< - pubsub_internal::RetryTraits>; + std::chrono::milliseconds maximum_duration() const { + return impl_.maximum_duration(); + } + + bool OnFailure(Status const& s) override { return impl_.OnFailure(s); } + bool IsExhausted() const override { return impl_.IsExhausted(); } + bool IsPermanentFailure(Status const& s) const override { + return impl_.IsPermanentFailure(s); + } + std::unique_ptr clone() const override { + return std::make_unique(impl_.maximum_duration()); + } + + // This is provided only for backwards compatibility. + using BaseType = RetryPolicy; + + private: + google::cloud::internal::LimitedTimeRetryPolicy + impl_; +}; GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace pubsub