@@ -334,9 +334,11 @@ AsyncConnectionImpl::AppendableObjectUploadImpl(AppendableUploadParams p) {
334334 auto factory = WriteResultFactory (
335335 [stub = stub_, cq = cq_, retry = std::move (retry),
336336 // NOLINTNEXTLINE(bugprone-lambda-function-name)
337- backoff = std::move (backoff), current, function_name = __func__](
337+ backoff = std::move (backoff), current, function_name = __func__,
338+ // Use shared_ptr to propagate RoutingHeaderOptions across retries.
339+ current_routing_options = std::make_shared<RoutingHeaderOptions>()](
338340 google::storage::v2::BidiWriteObjectRequest req) {
339- auto call = [stub, request = std::move (req)](
341+ auto call = [stub, request = std::move (req), current_routing_options ](
340342 CompletionQueue& cq,
341343 std::shared_ptr<grpc::ClientContext> context,
342344 google::cloud::internal::ImmutableOptions options,
@@ -351,9 +353,11 @@ AsyncConnectionImpl::AppendableObjectUploadImpl(AppendableUploadParams p) {
351353
352354 // Apply the routing header
353355 if (request.has_write_object_spec ())
354- ApplyRoutingHeaders (*context, request.write_object_spec ());
356+ ApplyRoutingHeaders (*context, request.write_object_spec (),
357+ *current_routing_options);
355358 else
356- ApplyRoutingHeaders (*context, request.append_object_spec ());
359+ ApplyRoutingHeaders (*context, request.append_object_spec (),
360+ *current_routing_options);
357361
358362 auto rpc = stub->AsyncBidiWriteObject (cq, std::move (context),
359363 std::move (options));
@@ -362,18 +366,23 @@ AsyncConnectionImpl::AppendableObjectUploadImpl(AppendableUploadParams p) {
362366 std::move (rpc));
363367 request.set_state_lookup (true );
364368 auto open = std::make_shared<WriteObject>(std::move (rpc), request);
365- return open->Call ().then ([open, &request](auto f) mutable {
366- open.reset ();
367- auto response = f.get ();
368- if (!response) {
369- google::rpc::Status grpc_status =
370- ExtractGrpcStatus (response.status ());
371- EnsureFirstMessageAppendObjectSpec (request, grpc_status);
372- ApplyWriteRedirectErrors (*request.mutable_append_object_spec (),
373- grpc_status);
374- }
375- return response;
376- });
369+ return open->Call ().then (
370+ [open, &request, current_routing_options](auto f) mutable {
371+ open.reset ();
372+ auto response = f.get ();
373+ if (!response) {
374+ google::rpc::Status grpc_status =
375+ ExtractGrpcStatus (response.status ());
376+ // Handle redirect and get info for updating routing options.
377+ BidiWriteRedirectInfo redirect_info =
378+ HandleBidiWriteRedirect (request, grpc_status);
379+
380+ // Update RoutingHeaderOptions for the next attempt.
381+ current_routing_options->routing_token =
382+ redirect_info.routing_token ;
383+ }
384+ return response;
385+ });
377386 };
378387
379388 return google::cloud::internal::AsyncRetryLoop (
0 commit comments