Skip to content

Commit 56269bc

Browse files
committed
fix(storage): Handle request transformation correctly after BidiWriteObject redirects
This commit addresses an issue where BidiWriteObject operations, particularly in cross-region redirect scenarios, would fail with a NOT_FOUND error. The root cause was that bucket information was not propagated in the request headers after the client received a redirect error from the service.
1 parent fc9f8f0 commit 56269bc

10 files changed

Lines changed: 605 additions & 98 deletions

google/cloud/storage/internal/async/connection_impl.cc

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,11 @@ AsyncConnectionImpl::AppendableObjectUploadImpl(AppendableUploadParams p) {
319319
auto factory = WriteResultFactory(
320320
[stub = stub_, cq = cq_, retry = std::move(retry),
321321
// NOLINTNEXTLINE(bugprone-lambda-function-name)
322-
backoff = std::move(backoff), current, function_name = __func__](
322+
backoff = std::move(backoff), current, function_name = __func__,
323+
// Use shared_ptr to propagate RoutingHeaderOptions across retries.
324+
current_routing_options = std::make_shared<RoutingHeaderOptions>()](
323325
google::storage::v2::BidiWriteObjectRequest req) {
324-
auto call = [stub, request = std::move(req)](
326+
auto call = [stub, request = std::move(req), current_routing_options](
325327
CompletionQueue& cq,
326328
std::shared_ptr<grpc::ClientContext> context,
327329
google::cloud::internal::ImmutableOptions options,
@@ -336,9 +338,11 @@ AsyncConnectionImpl::AppendableObjectUploadImpl(AppendableUploadParams p) {
336338

337339
// Apply the routing header
338340
if (request.has_write_object_spec())
339-
ApplyRoutingHeaders(*context, request.write_object_spec());
341+
ApplyRoutingHeaders(*context, request.write_object_spec(),
342+
*current_routing_options);
340343
else
341-
ApplyRoutingHeaders(*context, request.append_object_spec());
344+
ApplyRoutingHeaders(*context, request.append_object_spec(),
345+
*current_routing_options);
342346

343347
auto rpc = stub->AsyncBidiWriteObject(cq, std::move(context),
344348
std::move(options));
@@ -347,18 +351,23 @@ AsyncConnectionImpl::AppendableObjectUploadImpl(AppendableUploadParams p) {
347351
std::move(rpc));
348352
request.set_state_lookup(true);
349353
auto open = std::make_shared<WriteObject>(std::move(rpc), request);
350-
return open->Call().then([open, &request](auto f) mutable {
351-
open.reset();
352-
auto response = f.get();
353-
if (!response) {
354-
google::rpc::Status grpc_status =
355-
ExtractGrpcStatus(response.status());
356-
EnsureFirstMessageAppendObjectSpec(request, grpc_status);
357-
ApplyWriteRedirectErrors(*request.mutable_append_object_spec(),
358-
grpc_status);
359-
}
360-
return response;
361-
});
354+
return open->Call().then(
355+
[open, &request, current_routing_options](auto f) mutable {
356+
open.reset();
357+
auto response = f.get();
358+
if (!response) {
359+
google::rpc::Status grpc_status =
360+
ExtractGrpcStatus(response.status());
361+
// Handle redirect and get info for updating routing options.
362+
BidiWriteRedirectInfo redirect_info =
363+
HandleBidiWriteRedirect(request, grpc_status);
364+
365+
// Update RoutingHeaderOptions for the next attempt.
366+
current_routing_options->routing_token =
367+
redirect_info.routing_token;
368+
}
369+
return response;
370+
});
362371
};
363372

364373
return google::cloud::internal::AsyncRetryLoop(

0 commit comments

Comments
 (0)