fix: handle timer exceptions in grpc and http rpc backends (#102)

Improve error handling for async wait operations in both RPC backends by catching system errors, ensuring robustness against unexpected cancellations. This change addresses potential crashes and enhances stability during RPC service registration.
This commit is contained in:
zhangyi1357 2024-11-15 14:51:12 +08:00 committed by GitHub
parent eaa7c97557
commit e9d5fe05ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 9 deletions

View File

@ -282,7 +282,14 @@ bool GrpcRpcBackend::RegisterServiceFunc(
service_func_wrapper.service_func(service_invoke_wrapper_ptr); service_func_wrapper.service_func(service_invoke_wrapper_ptr);
co_await sig_timer_ptr->async_wait(boost::asio::use_awaitable); try {
co_await sig_timer_ptr->async_wait(boost::asio::use_awaitable);
} catch (const boost::system::system_error& e) {
if (e.code() != boost::asio::error::operation_aborted) [[unlikely]] {
AIMRT_ERROR("Http2 handle for rpc, async_wait get exception: {}", e.what());
ret_code = aimrt_rpc_status_code_t::AIMRT_RPC_STATUS_SVR_BACKEND_INTERNAL_ERROR;
}
}
AIMRT_CHECK_ERROR_THROW(ret_code == 0, "Handle rpc failed, ret_code: {}", ret_code); AIMRT_CHECK_ERROR_THROW(ret_code == 0, "Handle rpc failed, ret_code: {}", ret_code);

View File

@ -184,7 +184,6 @@ bool HttpRpcBackend::RegisterServiceFunc(
// 设置回调 // 设置回调
uint32_t ret_code = 0; uint32_t ret_code = 0;
auto sig_timer_ptr = std::make_shared<asio::steady_timer>(*io_ptr_, std::chrono::nanoseconds::max()); auto sig_timer_ptr = std::make_shared<asio::steady_timer>(*io_ptr_, std::chrono::nanoseconds::max());
std::atomic_bool handle_flag = false;
service_invoke_wrapper_ptr->callback = service_invoke_wrapper_ptr->callback =
[service_invoke_wrapper_ptr, [service_invoke_wrapper_ptr,
@ -195,7 +194,6 @@ bool HttpRpcBackend::RegisterServiceFunc(
service_rsp_ptr, service_rsp_ptr,
serialization_type{std::move(serialization_type)}, serialization_type{std::move(serialization_type)},
sig_timer_ptr, sig_timer_ptr,
&handle_flag,
&ret_code](aimrt::rpc::Status status) { &ret_code](aimrt::rpc::Status status) {
if (!status.OK()) [[unlikely]] { if (!status.OK()) [[unlikely]] {
ret_code = status.Code(); ret_code = status.Code();
@ -242,18 +240,19 @@ bool HttpRpcBackend::RegisterServiceFunc(
rsp.prepare_payload(); rsp.prepare_payload();
} }
} }
sig_timer_ptr->expires_at(std::chrono::steady_clock::time_point::min());
handle_flag.store(true);
// TODO: 这里可能会有提前cancel的风险。可能的解决方案多cancel几次
sig_timer_ptr->cancel();
}; };
// service rpc调用 // service rpc调用
service_func_wrapper.service_func(service_invoke_wrapper_ptr); service_func_wrapper.service_func(service_invoke_wrapper_ptr);
if (!handle_flag.load()) { try {
co_await sig_timer_ptr->async_wait(asio::use_awaitable); co_await sig_timer_ptr->async_wait(asio::use_awaitable);
} catch (const boost::system::system_error& e) {
if (e.code() != boost::asio::error::operation_aborted) [[unlikely]] {
AIMRT_ERROR("Http handle for rpc, async_wait get exception: {}", e.what());
ret_code = aimrt_rpc_status_code_t::AIMRT_RPC_STATUS_SVR_BACKEND_INTERNAL_ERROR;
}
} }
AIMRT_CHECK_ERROR_THROW(ret_code == 0, "Handle rpc failed, code: {}.", ret_code); AIMRT_CHECK_ERROR_THROW(ret_code == 0, "Handle rpc failed, code: {}.", ret_code);