@@ -26,8 +26,9 @@ auto constexpr kRefreshDeadlineOffsetMs = 1000;
2626} // namespace
2727
2828std::shared_ptr<QueryPlan> QueryPlan::Create (
29- CompletionQueue cq, google::bigtable::v2::PrepareQueryResponse response,
30- RefreshFn fn, std::shared_ptr<Clock> clock) {
29+ CompletionQueue cq,
30+ StatusOr<google::bigtable::v2::PrepareQueryResponse> response, RefreshFn fn,
31+ std::shared_ptr<Clock> clock) {
3132 auto plan = std::shared_ptr<QueryPlan>(new QueryPlan (
3233 std::move (cq), std::move (clock), std::move (fn), std::move (response)));
3334 plan->Initialize ();
@@ -36,7 +37,7 @@ std::shared_ptr<QueryPlan> QueryPlan::Create(
3637
3738void QueryPlan::Initialize () {
3839 std::unique_lock<std::mutex> lock (mu_);
39- ScheduleRefresh (lock);
40+ if (state_ == RefreshState:: kDone ) ScheduleRefresh (lock);
4041}
4142
4243// ScheduleRefresh should only be called after updating response_.
@@ -71,7 +72,7 @@ void QueryPlan::ExpiredRefresh() {
7172 state_ = RefreshState::kBegin ;
7273 }
7374 }
74- RefreshQueryPlan (RefreshMode:: kExpired );
75+ RefreshQueryPlan ();
7576}
7677
7778void QueryPlan::Invalidate (Status status,
@@ -82,26 +83,17 @@ void QueryPlan::Invalidate(Status status,
8283 // query plan, so we track what the previous plan id was.
8384 if (!IsRefreshing (lock) && old_query_plan_id_ != invalid_query_plan_id) {
8485 old_query_plan_id_ = invalid_query_plan_id;
86+ response_ = std::move (status);
8587 state_ = RefreshState::kBegin ;
8688 }
8789 }
88- RefreshQueryPlan (RefreshMode::kInvalidated , std::move (status));
8990}
9091
91- void QueryPlan::RefreshQueryPlan (RefreshMode mode, Status error ) {
92+ void QueryPlan::RefreshQueryPlan () {
9293 {
9394 std::unique_lock<std::mutex> lock_1 (mu_);
94- #ifdef GOOGLE_CLOUD_CPP_BIGTABLE_QUERY_PLAN_REFRESH_ASSERT
95- assert (waiting_threads_ >= 0 );
96- #endif
97- ++waiting_threads_;
9895 cond_.wait (lock_1, [this ] { return state_ != RefreshState::kPending ; });
99- --waiting_threads_;
100- #ifdef GOOGLE_CLOUD_CPP_BIGTABLE_QUERY_PLAN_REFRESH_ASSERT
101- assert (waiting_threads_ >= 0 );
102- #endif
10396 if (state_ == RefreshState::kDone ) return ;
104- if (mode == RefreshMode::kInvalidated ) response_ = std::move (error);
10597 state_ = RefreshState::kPending ;
10698 }
10799 auto response = refresh_fn_ ().get ();
@@ -114,7 +106,7 @@ void QueryPlan::RefreshQueryPlan(RefreshMode mode, Status error) {
114106 done = true ;
115107 // If we have to refresh an invalidated query plan, cancel any existing
116108 // timer before starting a new one.
117- refresh_timer_.cancel ();
109+ if (refresh_timer_. valid ()) refresh_timer_.cancel ();
118110 ScheduleRefresh (lock_2);
119111 } else {
120112 // If there are no waiting threads that could call the refresh_fn, then
@@ -124,13 +116,7 @@ void QueryPlan::RefreshQueryPlan(RefreshMode mode, Status error) {
124116 // If there are waiting threads, then we want to try again to get a
125117 // refreshed query plan, but we want to avoid a stampede of refresh RPCs
126118 // so we only notify one of the waiting threads.
127- #ifdef GOOGLE_CLOUD_CPP_BIGTABLE_QUERY_PLAN_REFRESH_ASSERT
128- assert (waiting_threads_ >= 0 );
129- #endif
130- if (waiting_threads_ == 0 ) {
131- state_ = RefreshState::kDone ;
132- done = true ;
133- }
119+ state_ = RefreshState::kBegin ;
134120 }
135121 }
136122 if (done) {
@@ -147,7 +133,7 @@ StatusOr<google::bigtable::v2::PrepareQueryResponse> QueryPlan::response() {
147133 return response_;
148134 }
149135 lock.unlock ();
150- RefreshQueryPlan (RefreshMode:: kAlreadyRefreshing );
136+ RefreshQueryPlan ();
151137 lock.lock ();
152138 }
153139
0 commit comments