|
33 | 33 | #include "google/cloud/storage/internal/async/writer_connection_buffered.h" |
34 | 34 | #include "google/cloud/storage/internal/async/writer_connection_finalized.h" |
35 | 35 | #include "google/cloud/storage/internal/async/writer_connection_impl.h" |
| 36 | +#include "google/cloud/storage/internal/async/writer_connection_resumed.h" |
36 | 37 | #include "google/cloud/storage/internal/crc32c.h" |
37 | 38 | #include "google/cloud/storage/internal/grpc/channel_refresh.h" |
38 | 39 | #include "google/cloud/storage/internal/grpc/configure_client_context.h" |
@@ -295,49 +296,63 @@ AsyncConnectionImpl::StartAppendableObjectUpload(AppendableUploadParams p) { |
295 | 296 | auto current = internal::MakeImmutableOptions(std::move(p.options)); |
296 | 297 | auto request = p.request; |
297 | 298 | std::int64_t persisted_size = 0; |
298 | | - auto hash_function = CreateHashFunction(*current); |
299 | | - auto retry = retry_policy(*current); |
300 | | - auto backoff = backoff_policy(*current); |
| 299 | + std::shared_ptr<storage::internal::HashFunction> hash_function = |
| 300 | + CreateHashFunction(*current); |
| 301 | + auto retry = std::shared_ptr<storage::RetryPolicy>(retry_policy(*current)); |
| 302 | + auto backoff = |
| 303 | + std::shared_ptr<storage::BackoffPolicy>(backoff_policy(*current)); |
301 | 304 | struct RequestPlaceholder {}; |
302 | 305 |
|
303 | | - auto call = [stub = stub_, request = std::move(request)]( |
304 | | - CompletionQueue& cq, |
305 | | - std::shared_ptr<grpc::ClientContext> context, |
306 | | - google::cloud::internal::ImmutableOptions options, |
307 | | - RequestPlaceholder const&) mutable |
308 | | - -> future<StatusOr<WriteObject::WriteResult>> { |
309 | | - auto rpc = |
310 | | - stub->AsyncBidiWriteObject(cq, std::move(context), std::move(options)); |
311 | | - request.set_state_lookup(true); |
312 | | - auto open = std::make_shared<WriteObject>(std::move(rpc), request); |
313 | | - return open->Call().then([open, &request](auto f) mutable { |
314 | | - auto response = f.get(); |
315 | | - if (!response) { |
316 | | - EnsureFirstMessageAppendObjectSpec(request); |
317 | | - ApplyWriteRedirectErrors(*request.mutable_append_object_spec(), |
318 | | - ExtractGrpcStatus(response.status())); |
319 | | - } |
320 | | - return response; |
321 | | - }); |
322 | | - }; |
| 306 | + using WriteResultFactory = |
| 307 | + std::function<future<StatusOr<WriteObject::WriteResult>>( |
| 308 | + google::storage::v2::BidiWriteObjectRequest)>; |
323 | 309 |
|
324 | | - auto transform = [current, request, persisted_size, |
325 | | - hash = std::move(hash_function)](auto f) mutable |
| 310 | + auto factory = WriteResultFactory( |
| 311 | + [stub = stub_, cq = cq_, retry = std::move(retry), |
| 312 | + backoff = std::move(backoff), current, function_name = __func__]( |
| 313 | + google::storage::v2::BidiWriteObjectRequest req) { |
| 314 | + auto call = [stub, request = std::move(req)]( |
| 315 | + CompletionQueue& cq_ref, |
| 316 | + std::shared_ptr<grpc::ClientContext> context, |
| 317 | + google::cloud::internal::ImmutableOptions options, |
| 318 | + RequestPlaceholder const&) mutable |
| 319 | + -> future<StatusOr<WriteObject::WriteResult>> { |
| 320 | + auto rpc = stub->AsyncBidiWriteObject(cq_ref, std::move(context), |
| 321 | + std::move(options)); |
| 322 | + request.set_state_lookup(true); |
| 323 | + auto open = std::make_shared<WriteObject>(std::move(rpc), request); |
| 324 | + return open->Call().then([open, &request](auto f) { |
| 325 | + auto response = f.get(); |
| 326 | + if (!response) { |
| 327 | + EnsureFirstMessageAppendObjectSpec(request); |
| 328 | + ApplyWriteRedirectErrors(*request.mutable_append_object_spec(), |
| 329 | + ExtractGrpcStatus(response.status())); |
| 330 | + } |
| 331 | + return response; |
| 332 | + }); |
| 333 | + }; |
| 334 | + |
| 335 | + return google::cloud::internal::AsyncRetryLoop( |
| 336 | + retry->clone(), backoff->clone(), Idempotency::kIdempotent, cq, |
| 337 | + std::move(call), std::move(current), RequestPlaceholder{}, |
| 338 | + function_name); |
| 339 | + }); |
| 340 | + |
| 341 | + auto pending = factory(std::move(request)); |
| 342 | + return pending.then( |
| 343 | + [current, request = std::move(p.request), persisted_size, |
| 344 | + hash = std::move(hash_function), fa = std::move(factory)](auto f) mutable |
326 | 345 | -> StatusOr< |
327 | 346 | std::unique_ptr<storage_experimental::AsyncWriterConnection>> { |
328 | | - auto rpc = f.get(); |
329 | | - if (!rpc) return std::move(rpc).status(); |
330 | | - return std::unique_ptr<storage_experimental::AsyncWriterConnection>( |
331 | | - std::make_unique<AsyncWriterConnectionImpl>( |
332 | | - current, std::move(request), std::move(rpc->stream), |
333 | | - std::move(hash), persisted_size, false)); |
334 | | - }; |
335 | | - |
336 | | - return google::cloud::internal::AsyncRetryLoop( |
337 | | - std::move(retry), std::move(backoff), Idempotency::kIdempotent, |
338 | | - cq_, std::move(call), std::move(current), RequestPlaceholder{}, |
339 | | - __func__) |
340 | | - .then(std::move(transform)); |
| 347 | + auto rpc = f.get(); |
| 348 | + if (!rpc) return std::move(rpc).status(); |
| 349 | + auto impl = std::make_unique<AsyncWriterConnectionImpl>( |
| 350 | + current, request, std::move(rpc->stream), hash, persisted_size, |
| 351 | + false); |
| 352 | + return MakeWriterConnectionResumed(std::move(fa), std::move(impl), |
| 353 | + std::move(request), std::move(hash), |
| 354 | + *current); |
| 355 | + }); |
341 | 356 | } |
342 | 357 |
|
343 | 358 | future<StatusOr<std::unique_ptr<storage_experimental::AsyncWriterConnection>>> |
|
0 commit comments