|
|
|
@ -126,13 +126,14 @@ void ServerTryCancelNonblocking(ServerContext* context) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void LoopUntilCancelled(Alarm* alarm, ServerContext* context, |
|
|
|
|
experimental::ServerCallbackRpcController* controller) { |
|
|
|
|
experimental::ServerCallbackRpcController* controller, |
|
|
|
|
int loop_delay_us) { |
|
|
|
|
if (!context->IsCancelled()) { |
|
|
|
|
alarm->experimental().Set( |
|
|
|
|
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), |
|
|
|
|
gpr_time_from_micros(1000, GPR_TIMESPAN)), |
|
|
|
|
[alarm, context, controller](bool) { |
|
|
|
|
LoopUntilCancelled(alarm, context, controller); |
|
|
|
|
gpr_time_from_micros(loop_delay_us, GPR_TIMESPAN)), |
|
|
|
|
[alarm, context, controller, loop_delay_us](bool) { |
|
|
|
|
LoopUntilCancelled(alarm, context, controller, loop_delay_us); |
|
|
|
|
}); |
|
|
|
|
} else { |
|
|
|
|
controller->Finish(Status::CANCELLED); |
|
|
|
@ -249,6 +250,25 @@ Status TestServiceImpl::CheckClientInitialMetadata(ServerContext* context, |
|
|
|
|
void CallbackTestServiceImpl::Echo( |
|
|
|
|
ServerContext* context, const EchoRequest* request, EchoResponse* response, |
|
|
|
|
experimental::ServerCallbackRpcController* controller) { |
|
|
|
|
CancelState* cancel_state = new CancelState; |
|
|
|
|
int server_use_cancel_callback = |
|
|
|
|
GetIntValueFromMetadata(kServerUseCancelCallback, |
|
|
|
|
context->client_metadata(), DO_NOT_USE_CALLBACK); |
|
|
|
|
if (server_use_cancel_callback != DO_NOT_USE_CALLBACK) { |
|
|
|
|
controller->SetCancelCallback([cancel_state] { |
|
|
|
|
EXPECT_FALSE(cancel_state->callback_invoked.exchange( |
|
|
|
|
true, std::memory_order_relaxed)); |
|
|
|
|
}); |
|
|
|
|
if (server_use_cancel_callback == MAYBE_USE_CALLBACK_EARLY_CANCEL) { |
|
|
|
|
EXPECT_TRUE(context->IsCancelled()); |
|
|
|
|
EXPECT_TRUE( |
|
|
|
|
cancel_state->callback_invoked.load(std::memory_order_relaxed)); |
|
|
|
|
} else { |
|
|
|
|
EXPECT_FALSE(context->IsCancelled()); |
|
|
|
|
EXPECT_FALSE( |
|
|
|
|
cancel_state->callback_invoked.load(std::memory_order_relaxed)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// A bit of sleep to make sure that short deadline tests fail
|
|
|
|
|
if (request->has_param() && request->param().server_sleep_us() > 0) { |
|
|
|
|
// Set an alarm for that much time
|
|
|
|
@ -256,11 +276,11 @@ void CallbackTestServiceImpl::Echo( |
|
|
|
|
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), |
|
|
|
|
gpr_time_from_micros(request->param().server_sleep_us(), |
|
|
|
|
GPR_TIMESPAN)), |
|
|
|
|
[this, context, request, response, controller](bool) { |
|
|
|
|
EchoNonDelayed(context, request, response, controller); |
|
|
|
|
[this, context, request, response, controller, cancel_state](bool) { |
|
|
|
|
EchoNonDelayed(context, request, response, controller, cancel_state); |
|
|
|
|
}); |
|
|
|
|
} else { |
|
|
|
|
EchoNonDelayed(context, request, response, controller); |
|
|
|
|
EchoNonDelayed(context, request, response, controller, cancel_state); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -279,7 +299,26 @@ void CallbackTestServiceImpl::CheckClientInitialMetadata( |
|
|
|
|
|
|
|
|
|
void CallbackTestServiceImpl::EchoNonDelayed( |
|
|
|
|
ServerContext* context, const EchoRequest* request, EchoResponse* response, |
|
|
|
|
experimental::ServerCallbackRpcController* controller) { |
|
|
|
|
experimental::ServerCallbackRpcController* controller, |
|
|
|
|
CancelState* cancel_state) { |
|
|
|
|
int server_use_cancel_callback = |
|
|
|
|
GetIntValueFromMetadata(kServerUseCancelCallback, |
|
|
|
|
context->client_metadata(), DO_NOT_USE_CALLBACK); |
|
|
|
|
|
|
|
|
|
// Safe to clear cancel callback even if it wasn't set
|
|
|
|
|
controller->ClearCancelCallback(); |
|
|
|
|
if (server_use_cancel_callback == MAYBE_USE_CALLBACK_EARLY_CANCEL || |
|
|
|
|
server_use_cancel_callback == MAYBE_USE_CALLBACK_LATE_CANCEL) { |
|
|
|
|
EXPECT_TRUE(context->IsCancelled()); |
|
|
|
|
EXPECT_TRUE(cancel_state->callback_invoked.load(std::memory_order_relaxed)); |
|
|
|
|
delete cancel_state; |
|
|
|
|
controller->Finish(Status::CANCELLED); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EXPECT_FALSE(cancel_state->callback_invoked.load(std::memory_order_relaxed)); |
|
|
|
|
delete cancel_state; |
|
|
|
|
|
|
|
|
|
if (request->has_param() && request->param().server_die()) { |
|
|
|
|
gpr_log(GPR_ERROR, "The request should not reach application handler."); |
|
|
|
|
GPR_ASSERT(0); |
|
|
|
@ -301,9 +340,11 @@ void CallbackTestServiceImpl::EchoNonDelayed( |
|
|
|
|
EXPECT_FALSE(context->IsCancelled()); |
|
|
|
|
context->TryCancel(); |
|
|
|
|
gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); |
|
|
|
|
// Now wait until it's really canceled
|
|
|
|
|
|
|
|
|
|
LoopUntilCancelled(&alarm_, context, controller); |
|
|
|
|
if (server_use_cancel_callback == DO_NOT_USE_CALLBACK) { |
|
|
|
|
// Now wait until it's really canceled
|
|
|
|
|
LoopUntilCancelled(&alarm_, context, controller, 1000); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -318,20 +359,11 @@ void CallbackTestServiceImpl::EchoNonDelayed( |
|
|
|
|
std::unique_lock<std::mutex> lock(mu_); |
|
|
|
|
signal_client_ = true; |
|
|
|
|
} |
|
|
|
|
std::function<void(bool)> recurrence = [this, context, request, controller, |
|
|
|
|
&recurrence](bool) { |
|
|
|
|
if (!context->IsCancelled()) { |
|
|
|
|
alarm_.experimental().Set( |
|
|
|
|
gpr_time_add( |
|
|
|
|
gpr_now(GPR_CLOCK_REALTIME), |
|
|
|
|
gpr_time_from_micros(request->param().client_cancel_after_us(), |
|
|
|
|
GPR_TIMESPAN)), |
|
|
|
|
recurrence); |
|
|
|
|
} else { |
|
|
|
|
controller->Finish(Status::CANCELLED); |
|
|
|
|
if (server_use_cancel_callback == DO_NOT_USE_CALLBACK) { |
|
|
|
|
// Now wait until it's really canceled
|
|
|
|
|
LoopUntilCancelled(&alarm_, context, controller, |
|
|
|
|
request->param().client_cancel_after_us()); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
recurrence(true); |
|
|
|
|
return; |
|
|
|
|
} else if (request->has_param() && |
|
|
|
|
request->param().server_cancel_after_us()) { |
|
|
|
|