Invalidate ExecCtx now for each queued call that we resume in the client channel filter (#26632)

* Invalidate ExecCtx now for each iteration of the loop to
ensure we get back to the correct time.

* Updated comments
reviewable/pr26669/r1
donnadionne 3 years ago committed by GitHub
parent 73e65b88ba
commit c165c71bd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      src/core/ext/filters/client_channel/client_channel.cc

@ -1548,6 +1548,15 @@ void ClientChannel::UpdateServiceConfigInDataPlaneLocked() {
// Process calls that were queued waiting for the resolver result. // Process calls that were queued waiting for the resolver result.
for (ResolverQueuedCall* call = resolver_queued_calls_; call != nullptr; for (ResolverQueuedCall* call = resolver_queued_calls_; call != nullptr;
call = call->next) { call = call->next) {
// If there are a lot of queued calls here, resuming them all may cause us
// to stay inside C-core for a long period of time. All of that work would
// be done using the same ExecCtx instance and therefore the same cached
// value of "now". The longer it takes to finish all of this work and exit
// from C-core, the more stale the cached value of "now" may become. This
// can cause problems whereby (e.g.) we calculate a timer deadline based
// on the stale value, which results in the timer firing too early. To
// avoid this, we invalidate the cached value for each call we process.
ExecCtx::Get()->InvalidateNow();
grpc_call_element* elem = call->elem; grpc_call_element* elem = call->elem;
CallData* calld = static_cast<CallData*>(elem->call_data); CallData* calld = static_cast<CallData*>(elem->call_data);
grpc_error_handle error = GRPC_ERROR_NONE; grpc_error_handle error = GRPC_ERROR_NONE;
@ -1660,6 +1669,15 @@ void ClientChannel::UpdateStateAndPickerLocked(
// Re-process queued picks. // Re-process queued picks.
for (LbQueuedCall* call = lb_queued_calls_; call != nullptr; for (LbQueuedCall* call = lb_queued_calls_; call != nullptr;
call = call->next) { call = call->next) {
// If there are a lot of queued calls here, resuming them all may cause us
// to stay inside C-core for a long period of time. All of that work would
// be done using the same ExecCtx instance and therefore the same cached
// value of "now". The longer it takes to finish all of this work and exit
// from C-core, the more stale the cached value of "now" may become. This
// can cause problems whereby (e.g.) we calculate a timer deadline based
// on the stale value, which results in the timer firing too early. To
// avoid this, we invalidate the cached value for each call we process.
ExecCtx::Get()->InvalidateNow();
grpc_error_handle error = GRPC_ERROR_NONE; grpc_error_handle error = GRPC_ERROR_NONE;
if (call->lb_call->PickSubchannelLocked(&error)) { if (call->lb_call->PickSubchannelLocked(&error)) {
call->lb_call->AsyncPickDone(error); call->lb_call->AsyncPickDone(error);

Loading…
Cancel
Save