Skip to content

Commit

Permalink
fix: handle timer exceptions in grpc and http rpc backends (AimRT#102)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
zhangyi1357 authored Nov 15, 2024
1 parent eaa7c97 commit e9d5fe0
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
9 changes: 8 additions & 1 deletion src/plugins/grpc_plugin/grpc_rpc_backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,14 @@ bool GrpcRpcBackend::RegisterServiceFunc(

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);

Expand Down
15 changes: 7 additions & 8 deletions src/plugins/net_plugin/http/http_rpc_backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ bool HttpRpcBackend::RegisterServiceFunc(
// 设置回调
uint32_t ret_code = 0;
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,
Expand All @@ -195,7 +194,6 @@ bool HttpRpcBackend::RegisterServiceFunc(
service_rsp_ptr,
serialization_type{std::move(serialization_type)},
sig_timer_ptr,
&handle_flag,
&ret_code](aimrt::rpc::Status status) {
if (!status.OK()) [[unlikely]] {
ret_code = status.Code();
Expand Down Expand Up @@ -242,18 +240,19 @@ bool HttpRpcBackend::RegisterServiceFunc(
rsp.prepare_payload();
}
}

handle_flag.store(true);

// TODO: 这里可能会有提前cancel的风险。可能的解决方案:多cancel几次?
sig_timer_ptr->cancel();
sig_timer_ptr->expires_at(std::chrono::steady_clock::time_point::min());
};

// service rpc调用
service_func_wrapper.service_func(service_invoke_wrapper_ptr);

if (!handle_flag.load()) {
try {
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);
Expand Down

0 comments on commit e9d5fe0

Please sign in to comment.