|
19 | 19 | #include "google/cloud/bigtable/internal/bulk_mutator.h" |
20 | 20 | #include "google/cloud/bigtable/internal/default_row_reader.h" |
21 | 21 | #include "google/cloud/bigtable/internal/defaults.h" |
| 22 | +#include "google/cloud/bigtable/internal/logging_result_set_reader.h" |
22 | 23 | #include "google/cloud/bigtable/internal/operation_context.h" |
23 | 24 | #include "google/cloud/bigtable/internal/partial_result_set_reader.h" |
24 | 25 | #include "google/cloud/bigtable/internal/partial_result_set_resume.h" |
25 | 26 | #include "google/cloud/bigtable/internal/partial_result_set_source.h" |
| 27 | +#include "google/cloud/bigtable/internal/retry_traits.h" |
| 28 | +#include "google/cloud/bigtable/internal/rpc_policy_parameters.h" |
26 | 29 | #include "google/cloud/bigtable/options.h" |
27 | 30 | #include "google/cloud/bigtable/results.h" |
| 31 | +#include "google/cloud/bigtable/retry_policy.h" |
28 | 32 | #include "google/cloud/background_threads.h" |
29 | 33 | #include "google/cloud/grpc_options.h" |
30 | 34 | #include "google/cloud/idempotency.h" |
@@ -65,6 +69,15 @@ inline bool enable_server_retries(Options const& options) { |
65 | 69 | return options.get<EnableServerRetriesOption>(); |
66 | 70 | } |
67 | 71 |
|
| 72 | +inline bool RpcStreamTracingEnabled() { |
| 73 | + return internal::Contains( |
| 74 | + internal::CurrentOptions().get<LoggingComponentsOption>(), "rpc-streams"); |
| 75 | +} |
| 76 | + |
| 77 | +inline TracingOptions const& RpcTracingOptions() { |
| 78 | + return internal::CurrentOptions().get<GrpcTracingOptionsOption>(); |
| 79 | +} |
| 80 | + |
68 | 81 | // This function allows for ReadRow and ReadRowsFull to provide an instance of |
69 | 82 | // an OperationContext specific to that operation. |
70 | 83 | bigtable::RowReader ReadRowsHelper( |
@@ -138,21 +151,6 @@ class DefaultPartialResultSetReader |
138 | 151 | Status final_status_; |
139 | 152 | }; |
140 | 153 |
|
141 | | -class StatusOnlyResultSetSource : public bigtable::ResultSourceInterface { |
142 | | - public: |
143 | | - explicit StatusOnlyResultSetSource(google::cloud::Status status) |
144 | | - : status_(std::move(status)) {} |
145 | | - ~StatusOnlyResultSetSource() override = default; |
146 | | - |
147 | | - StatusOr<bigtable::QueryRow> NextRow() override { return status_; } |
148 | | - absl::optional<google::bigtable::v2::ResultSetMetadata> Metadata() override { |
149 | | - return {}; |
150 | | - } |
151 | | - |
152 | | - private: |
153 | | - google::cloud::Status status_; |
154 | | -}; |
155 | | - |
156 | 154 | template <typename ResultType> |
157 | 155 | ResultType MakeStatusOnlyResult(Status status) { |
158 | 156 | return ResultType( |
@@ -836,44 +834,86 @@ DataConnectionImpl::CreateResumableReader( |
836 | 834 | std::move(stream)); |
837 | 835 | } |
838 | 836 |
|
839 | | -StatusOr<bigtable::RowStream> DataConnectionImpl::ExecuteQuery( |
840 | | - bigtable::ExecuteQueryParams const& params) { |
| 837 | +bigtable::RowStream DataConnectionImpl::ExecuteQuery( |
| 838 | + bigtable::ExecuteQueryParams params) { |
841 | 839 | auto current = google::cloud::internal::SaveCurrentOptions(); |
842 | | - StatusOr<google::bigtable::v2::ResultSetMetadata> status_or_metadata = |
843 | | - params.bound_query.response()->metadata(); |
844 | 840 | google::bigtable::v2::ExecuteQueryRequest request = |
845 | 841 | params.bound_query.ToRequestProto(); |
846 | 842 | request.set_app_profile_id(app_profile_id(*current)); |
847 | | - if (!status_or_metadata) { |
848 | | - return status_or_metadata.status(); |
849 | | - } |
850 | | - google::bigtable::v2::ResultSetMetadata metadata = |
851 | | - *std::move(status_or_metadata); |
| 843 | + |
| 844 | + auto const tracing_enabled = RpcStreamTracingEnabled(); |
| 845 | + auto const& tracing_options = RpcTracingOptions(); |
852 | 846 |
|
853 | 847 | auto retry_resume_fn = |
854 | | - [this, retry_policy_prototype = retry_policy(*current), |
855 | | - backoff_policy_prototype = backoff_policy(*current)]( |
856 | | - google::bigtable::v2::ResultSetMetadata metadata, |
857 | | - google::bigtable::v2::ExecuteQueryRequest const& initial_request) |
| 848 | + [stub = stub_, retry_policy_prototype = retry_policy(*current), |
| 849 | + backoff_policy_prototype = backoff_policy(*current), tracing_enabled, |
| 850 | + tracing_options](google::bigtable::v2::ExecuteQueryRequest& request, |
| 851 | + google::bigtable::v2::ResultSetMetadata metadata, |
| 852 | + std::shared_ptr<OperationContext> const&) mutable |
858 | 853 | -> StatusOr<std::unique_ptr<bigtable::ResultSourceInterface>> { |
859 | | - auto factory = absl::bind_front(&DataConnectionImpl::CreateResumableReader, |
860 | | - this, initial_request); |
| 854 | + auto factory = [stub, request, tracing_enabled, |
| 855 | + tracing_options](std::string const& resume_token) mutable { |
| 856 | + if (!resume_token.empty()) request.set_resume_token(resume_token); |
| 857 | + auto context = std::make_shared<grpc::ClientContext>(); |
| 858 | + auto const& options = internal::CurrentOptions(); |
| 859 | + internal::ConfigureContext(*context, options); |
| 860 | + auto stream = stub->ExecuteQuery(context, options, request); |
| 861 | + std::unique_ptr<PartialResultSetReader> reader = |
| 862 | + std::make_unique<DefaultPartialResultSetReader>(std::move(context), |
| 863 | + std::move(stream)); |
| 864 | + if (tracing_enabled) { |
| 865 | + reader = std::make_unique<LoggingResultSetReader>(std::move(reader), |
| 866 | + tracing_options); |
| 867 | + } |
| 868 | + return reader; |
| 869 | + }; |
861 | 870 |
|
862 | | - auto resume_reader = std::make_unique<PartialResultSetResume>( |
| 871 | + auto rpc = std::make_unique<PartialResultSetResume>( |
863 | 872 | std::move(factory), Idempotency::kIdempotent, |
864 | 873 | retry_policy_prototype->clone(), backoff_policy_prototype->clone()); |
865 | 874 |
|
866 | | - return PartialResultSetSource::Create(std::move(metadata), |
867 | | - std::move(resume_reader)); |
| 875 | + return PartialResultSetSource::Create(std::move(metadata), std::move(rpc)); |
868 | 876 | }; |
869 | 877 |
|
870 | | - auto response = retry_resume_fn(metadata, request); |
871 | | - if (!response) { |
872 | | - auto status = std::move(response).status(); |
873 | | - return MakeStatusOnlyResult<bigtable::RowStream>(std::move(status)); |
| 878 | + auto operation_context = std::make_shared<OperationContext>(); |
| 879 | + |
| 880 | + auto query_plan = params.bound_query.query_plan_; |
| 881 | + auto operation_retry_policy = retry_policy(*current); |
| 882 | + auto operation_backoff_policy = backoff_policy(*current); |
| 883 | + Status last_status; |
| 884 | + |
| 885 | + while (!operation_retry_policy->IsExhausted()) { |
| 886 | + StatusOr<google::bigtable::v2::PrepareQueryResponse> query_plan_data = |
| 887 | + query_plan->response(); |
| 888 | + |
| 889 | + if (query_plan_data.ok()) { |
| 890 | + request.set_prepared_query(query_plan_data->prepared_query()); |
| 891 | + auto reader = retry_resume_fn(request, query_plan_data->metadata(), |
| 892 | + operation_context); |
| 893 | + if (reader.ok()) { |
| 894 | + return bigtable::RowStream(*std::move(reader)); |
| 895 | + } |
| 896 | + if (SafeGrpcRetryAllowingQueryPlanRefresh::IsQueryPlanExpired( |
| 897 | + reader.status())) { |
| 898 | + query_plan->Invalidate(reader.status(), |
| 899 | + query_plan_data->prepared_query()); |
| 900 | + } |
| 901 | + last_status = reader.status(); |
| 902 | + } else { |
| 903 | + last_status = query_plan_data.status(); |
| 904 | + } |
| 905 | + |
| 906 | + auto delay = |
| 907 | + internal::Backoff(last_status, __func__, *operation_retry_policy, |
| 908 | + *operation_backoff_policy, Idempotency::kIdempotent, |
| 909 | + false /* enable_server_retries */); |
| 910 | + if (!delay) break; |
| 911 | + std::this_thread::sleep_for(*delay); |
874 | 912 | } |
875 | | - return bigtable::RowStream(*std::move(response)); |
876 | | -}; |
| 913 | + return bigtable::RowStream( |
| 914 | + std::make_unique<StatusOnlyResultSetSource>(internal::RetryLoopError( |
| 915 | + last_status, __func__, operation_retry_policy->IsExhausted()))); |
| 916 | +} |
877 | 917 |
|
878 | 918 | GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END |
879 | 919 | } // namespace bigtable_internal |
|
0 commit comments