/*!

@page spanner-retry-policies Override Retry, Backoff, and Re-Run Policies

When it is safe to do so, the library automatically retries requests
that fail due to a transient error. The library then uses [exponential
backoff] to delay before trying again. Which operations are considered
safe to retry, which errors are treated as transient failures, the
parameters of the exponential backoff algorithm, and the limits of
library retries, are all configurable via policies.

The library provides defaults for any policy that is not set. This
document provides examples showing how to override those default
policies.

The policies can be set when a [`Connection`], object is created. Some
of the policies can also be overridden when the corresponding [`Client`]
object is created. This can be useful if multiple `Client` objects share
the same `Connection` object, but you want different retry behavior in
some of those clients. Finally, some retry policies can be overridden
when calling a specific `Client` member function.

The library uses two different policy options to control the retry
loops.

@section spanner-override-retry-retry-policy Configuring the transient errors and retry duration

The `SpannerRetryPolicyOption` controls:

- Which errors are to be treated as transient errors.
- How long the library will keep retrying transient errors.

You can provide your own class for this option. The library also
provides two built-in policies:

- `LimitedErrorCountRetryPolicy`: stops retrying after a specified
  number of transient errors.
- `LimitedTimeRetryPolicy`: stops retrying after a specified time.

In most cases, only [kUnavailable](@ref google::cloud::StatusCode) and
[kResourceExhausted](@ref google::cloud::StatusCode) are treated as a
transient errors.

@see google::cloud::spanner::SpannerRetryPolicyOption
@see google::cloud::spanner::RetryPolicy
@see google::cloud::spanner::LimitedErrorCountRetryPolicy
@see google::cloud::spanner::LimitedTimeRetryPolicy

@section spanner-override-retry-backoff-policy Controlling the backoff algorithm

The `SpannerBackoffPolicyOption` controls how long the client library
will wait before retrying a request that failed with a transient
error. You can provide your own class for this option.

The only built-in backoff policy is `ExponentialBackoffPolicy`. This
class implements a truncated exponential backoff algorithm, with jitter.
In summary, it doubles the current backoff time after each failure. The
actual backoff time for an RPC is chosen at random, but never exceeds
the current backoff. The current backoff is doubled after each failure,
but never exceeds (or is "truncated" if it reaches) a prescribed
maximum.

@see google::cloud::spanner::SpannerBackoffPolicyOption
@see google::cloud::spanner::BackoffPolicy
@see google::cloud::spanner::ExponentialBackoffPolicy

@section spanner-override-retry-example Example

For example, this will override the retry and backoff policies through
options passed to `spanner::MakeConnection()`:

@snippet google/cloud/spanner/samples/samples.cc custom-retry-policy

@section spanner-override-rerun-commit-policy Controlling which commits are rerunnable

The library also uses a special `TransactionRerunPolicy` to control
how the commit of a read-write transaction will be reattempted
after a failure with a rerunnable status (typically [kAborted](@ref
google::cloud::StatusCode)). The lock priority of the commit increases
after each rerun, meaning that the next attempt has a slightly better
chance of success.

You can provide your own class for this policy. The library also
provides two built-in policies:

- `LimitedErrorCountTransactionRerunPolicy`: stops rerunning the commit
  after a specified number of rerunnable errors.
- `LimitedTimeTransactionRerunPolicy`: stops rerunnable the commit
  after a specified time.

@snippet google/cloud/spanner/samples/samples.cc commit-with-policies

@see google::cloud::spanner::TransactionRerunPolicy
@see google::cloud::spanner::LimitedErrorCountTransactionRerunPolicy
@see google::cloud::spanner::LimitedTimeTransactionRerunPolicy

@section spanner-override-retry-more-information More Information

@see google::cloud::Options
@see google::cloud::RetryPolicy
@see google::cloud::BackoffPolicy

Follow these links to find examples for other spanner `*Client` classes:

- [\c InstanceAdminClient](@ref spanner_admin::InstanceAdminClient-retry-snippet)
- [\c DatabaseAdminClient](@ref spanner_admin::DatabaseAdminClient-retry-snippet)

[exponential backoff]: https://en.wikipedia.org/wiki/Exponential_backoff
[`Connection`]: @ref google::cloud::spanner::Connection
[`Client`]: @ref google::cloud::spanner::Client

*/

/*! @page spanner_admin::InstanceAdminClient-retry-snippet Override spanner_admin::InstanceAdminClient Retry Policies

This shows how to override the retry policies for `spanner_admin::InstanceAdminClient`:

@snippet google/cloud/spanner/samples/samples.cc custom-instance-admin-policies

This shows how to create a custom idempotency policy:

@snippet google/cloud/spanner/admin/samples/instance_admin_client_samples.cc custom-idempotency-policy

[`spanner_admin::InstanceAdminClient`]: @ref google::cloud::spanner_admin::InstanceAdminClient

*/

/*! @page spanner_admin::DatabaseAdminClient-retry-snippet Override spanner_admin::DatabaseAdminClient Retry Policies

This shows how to override the retry policies for `spanner_admin::DatabaseAdminClient`:

@snippet google/cloud/spanner/samples/samples.cc custom-database-admin-policies

This shows how to create a custom idempotency policy:

@snippet google/cloud/spanner/admin/samples/database_admin_client_samples.cc custom-idempotency-policy

[`spanner_admin::DatabaseAdminClient`]: @ref google::cloud::spanner_admin::DatabaseAdminClient

*/
