Skip to content
This repository was archived by the owner on Dec 8, 2021. It is now read-only.

Commit 9a64e06

Browse files
authored
feat: allow users to configure retry policies (#1111)
Add an overload for `spanner::MakeConnection()` which allows users to override the retry and backoff policies. Implement an example showing how to use this overload.
1 parent 7d4f9d6 commit 9a64e06

4 files changed

Lines changed: 69 additions & 1 deletion

File tree

google/cloud/spanner/client.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,22 @@ StatusOr<PartitionedDmlResult> Client::ExecutePartitionedDml(
221221

222222
std::shared_ptr<Connection> MakeConnection(Database const& db,
223223
ConnectionOptions const& options) {
224+
return MakeConnection(db, options, internal::DefaultConnectionRetryPolicy(),
225+
internal::DefaultConnectionBackoffPolicy());
226+
}
227+
228+
std::shared_ptr<Connection> MakeConnection(
229+
Database const& db, ConnectionOptions const& options,
230+
std::unique_ptr<RetryPolicy> retry_policy,
231+
std::unique_ptr<BackoffPolicy> backoff_policy) {
224232
std::vector<std::shared_ptr<internal::SpannerStub>> stubs;
225233
int num_channels = std::min(options.num_channels(), 1);
226234
stubs.reserve(num_channels);
227235
for (int channel_id = 0; channel_id < num_channels; ++channel_id) {
228236
stubs.push_back(internal::CreateDefaultSpannerStub(options, channel_id));
229237
}
230-
return internal::MakeConnection(db, std::move(stubs));
238+
return internal::MakeConnection(db, std::move(stubs), std::move(retry_policy),
239+
std::move(backoff_policy));
231240
}
232241

233242
} // namespace SPANNER_CLIENT_NS

google/cloud/spanner/client.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,20 @@ class Client {
540540
std::shared_ptr<Connection> MakeConnection(
541541
Database const& db, ConnectionOptions const& options = ConnectionOptions());
542542

543+
/**
544+
* @copydoc MakeConnection(Database const&, ConnectionOptions const&)
545+
*
546+
* @param retry_policy override the default `RetryPolicy`, controls for how long
547+
* does the returned `Connection` object retry requests on transient
548+
* failures.
549+
* @param backoff_policy override the default `BackoffPolicy`, controls for how
550+
* long does the `Connection` object waits before retrying a failed request.
551+
*/
552+
std::shared_ptr<Connection> MakeConnection(
553+
Database const& db, ConnectionOptions const& options,
554+
std::unique_ptr<RetryPolicy> retry_policy,
555+
std::unique_ptr<BackoffPolicy> backoff_policy);
556+
543557
} // namespace SPANNER_CLIENT_NS
544558
} // namespace spanner
545559
} // namespace cloud

google/cloud/spanner/doc/spanner-main.dox

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ The default policies are to continue retrying for up to 15 minutes, and to
223223
use truncated (at 5 minutes) exponential backoff, doubling the maximum backoff
224224
period between retries.
225225

226+
@snippet samples.cc custom-retry-policy
227+
226228
@see [LimitedTimeRetryPolicy](@ref google::cloud::spanner::v0::LimitedTimeRetryPolicy)
227229
and [LimitedErrorCountRetryPolicy](@ref google::cloud::spanner::v0::LimitedErrorCountRetryPolicy)
228230
for alternative retry policies.

google/cloud/spanner/samples/samples.cc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,6 +1605,44 @@ void ExampleStatusOr(google::cloud::spanner::Client client) {
16051605
(std::move(client));
16061606
}
16071607

1608+
void CustomRetryPolicy(std::vector<std::string> argv) {
1609+
if (argv.size() != 3) {
1610+
throw std::runtime_error(
1611+
"custom-retry-policy <project-id> <instance-id> <database-id>");
1612+
}
1613+
//! [custom-retry-policy]
1614+
namespace spanner = google::cloud::spanner;
1615+
[](std::string const& project_id, std::string const& instance_id,
1616+
std::string const& database_id) {
1617+
auto client = spanner::Client(spanner::MakeConnection(
1618+
spanner::Database(project_id, instance_id, database_id),
1619+
spanner::ConnectionOptions{},
1620+
// Retry for at most 25 minutes.
1621+
spanner::LimitedTimeRetryPolicy(
1622+
/*maximum_duration=*/std::chrono::minutes(25))
1623+
.clone(),
1624+
// Use an truncated exponential backoff with jitter to wait between
1625+
// retries:
1626+
// https://en.wikipedia.org/wiki/Exponential_backoff
1627+
// https://cloud.google.com/storage/docs/exponential-backoff
1628+
spanner::ExponentialBackoffPolicy(
1629+
/*initial_delay=*/std::chrono::seconds(2),
1630+
/*maximum_delay=*/std::chrono::minutes(10),
1631+
/*scaling=*/1.5)
1632+
.clone()));
1633+
1634+
auto rows =
1635+
client.ExecuteQuery(spanner::SqlStatement("SELECT 'Hello World'"));
1636+
1637+
for (auto const& row : spanner::StreamOf<std::tuple<std::string>>(rows)) {
1638+
if (!row) throw std::runtime_error(row.status().message());
1639+
std::cout << std::get<0>(*row) << "\n";
1640+
}
1641+
}
1642+
//! [custom-retry-policy]
1643+
(argv[0], argv[1], argv[2]);
1644+
}
1645+
16081646
class RemoteConnectionFake {
16091647
public:
16101648
void SendBinaryStringData(std::string const& serialized_partition) {
@@ -1835,6 +1873,7 @@ int RunOneCommand(std::vector<std::string> argv) {
18351873
make_command_entry("partition-read", &PartitionRead),
18361874
make_command_entry("partition-query", &PartitionQuery),
18371875
make_command_entry("example-status-or", &ExampleStatusOr),
1876+
{"custom-retry-policy", &CustomRetryPolicy},
18381877
};
18391878

18401879
static std::string usage_msg = [&argv, &commands] {
@@ -2086,6 +2125,10 @@ void RunAll() {
20862125
std::cout << "\nRunning example-status-or sample\n";
20872126
ExampleStatusOr(client);
20882127

2128+
std::cout << "\nRunning custom-retry-policy sample\n";
2129+
RunOneCommand(
2130+
{"", "custom-retry-policy", project_id, instance_id, database_id});
2131+
20892132
std::cout << "\nRunning spanner_dml_partitioned_update sample\n";
20902133
DmlPartitionedUpdate(client);
20912134

0 commit comments

Comments
 (0)