/*!

@page bigtable-override-retry Override Retry, Backoff, and Idempotency 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 backoff
before trying again. Which operations are considered safe to retry, which
errors are treated as transient failures, the details of the exponential backoff
algorithm, and for how long the library retries are all configurable via
policies.

This document provides examples showing how to override the default policies.

The policies can be set when a [`DataConnection`],
[`BigtableInstanceAdminConnection`], or [`BigtableTableAdminConnection`]
object is created. The library provides default policies for any policy that
is not set.

The application can also override some (or all) policies when the corresponding
[`Table`], [`BigtableInstanceAdminClient`], or [`BigtableTableAdminClient`]
object is created. This can be useful if multiple `Table` (or `*Client`) objects
share the same `*Connection` object, but you want different retry behavior in
some of the clients.

Finally, the application can override some retry policies when calling a
specific member function.

The library uses three different options to control the retry loop. The options
have per-client names

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

The `*RetryPolicyOption` 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.

Note that a library may have more than one version of these classes. Their name
match the `*Client` and `*Connection` object they are intended to be used
with. Some `*Client` objects treat different error codes as transient errors.
In most cases, only [kUnavailable](@ref google::cloud::StatusCode) is treated
as a transient error.

@see google::cloud::bigtable::DataRetryPolicyOption
@see google::cloud::bigtable::DataRetryPolicy
@see google::cloud::bigtable::DataLimitedTimeRetryPolicy
@see google::cloud::bigtable::DataLimitedErrorCountRetryPolicy
@see google::cloud::bigtable_admin::BigtableTableAdminRetryPolicy
@see google::cloud::bigtable_admin::BigtableInstanceAdminRetryPolicy

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

The `*BackoffPolicyOption` 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`](@ref google::cloud::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::bigtable::DataBackoffPolicyOption
@see google::cloud::bigtable_admin::BigtableTableAdminBackoffPolicyOption
@see google::cloud::bigtable_admin::BigtableInstanceAdminBackoffPolicyOption

@section bigtable-override-retry-idempotency-policy Controlling which operations are retryable

The `*IdempotencyPolicyOption` controls which requests are retryable, as some
requests are never safe to retry.

Only one built-in idempotency policy is provided by the library. The name
matches the name of the client it is intended for. For example,
`BigtableTableAdminClient` will use
`BigtableTableAdminConnectionIdempotencyPolicy`.

In the case of data operations, only mutations need to be considered.
The [`Table`] class uses [`IdempotentMutationPolicy`]. Mutations that use
server-assigned timestamps are not considered idempotent by default. Mutations
that use client-assigned timestamps are idempontent by default.

@see google::cloud::bigtable::IdempotentMutationPolicy
@see google::cloud::bigtable::IdempotentMutationPolicyOption
@see google::cloud::bigtable_admin::BigtableTableAdminConnectionIdempotencyPolicy
@see google::cloud::bigtable_admin::BigtableTableAdminConnectionIdempotencyPolicyOption
@see google::cloud::bigtable_admin::BigtableInstanceAdminConnectionIdempotencyPolicy
@see google::cloud::bigtable_admin::BigtableInstanceAdminConnectionIdempotencyPolicyOption

@section bigtable-override-retry-example Example

For example, this will override the retry policies for `bigtable::Table`:

@snippet client_samples.cc set-retry-policy


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

- [\c BigtableInstanceAdminClient](@ref admin::BigtableInstanceAdminClient-retry-snippet)
- [\c BigtableTableAdminClient](@ref admin::BigtableTableAdminClient-retry-snippet)

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

@see google::cloud::Options
@see google::cloud::BackoffPolicy
@see google::cloud::ExponentialBackoffPolicy

[exponential backoff]: https://en.wikipedia.org/wiki/Exponential_backoff
[`DataConnection`]: @ref google::cloud::bigtable::DataConnection
[`Table`]: @ref google::cloud::bigtable::Table
[`BigtableInstanceAdminConnection`]: @ref google::cloud::bigtable_admin::BigtableInstanceAdminConnection
[`BigtableInstanceAdminClient`]: @ref google::cloud::bigtable_admin::BigtableInstanceAdminClient
[`BigtableTableAdminConnection`]: @ref google::cloud::bigtable_admin::BigtableTableAdminConnection
[`BigtableTableAdminClient`]: @ref google::cloud::bigtable_admin::BigtableTableAdminClient
[`IdempotentMutationPolicy`]: @ref google::cloud::bigtable::IdempotentMutationPolicy

*/

/*! @page admin::BigtableInstanceAdminClient-retry-snippet Override admin::BigtableInstanceAdminClient Retry Policies

This shows how to override the retry policies for admin::BigtableInstanceAdminClient:

@snippet google/cloud/bigtable/admin/samples/bigtable_instance_admin_client_samples.cc set-retry-policy

Assuming you have created a custom idempotency policy. Such as:

@snippet google/cloud/bigtable/admin/samples/bigtable_instance_admin_client_samples.cc custom-idempotency-policy

*/

/*! @page admin::BigtableTableAdminClient-retry-snippet Override admin::BigtableTableAdminClient Retry Policies

This shows how to override the retry policies for admin::BigtableTableAdminClient:

@snippet google/cloud/bigtable/admin/samples/bigtable_table_admin_client_samples.cc set-retry-policy

Assuming you have created a custom idempotency policy. Such as:

@snippet google/cloud/bigtable/admin/samples/bigtable_table_admin_client_samples.cc custom-idempotency-policy

*/
