GRPC同步请求设置ClientContext截止时间触发删除构造函数调用错误求助
GRPC ClientContext set_deadline 编译错误解决
问题场景
为GRPC同步请求配置grpc::ClientContext时,设置deadline的代码触发编译错误,移除Context相关代码后程序可正常运行。
函数代码
grpc::Status Connection::syncLookup(Foo::LookupRequest &request, Foo::LookupResponse *response) { bool failure = false; grpc::ClientContext ctx; Clock::time_point now = Clock::now(); auto time_since_epoch = std::chrono::duration_cast<Ms>(now.time_since_epoch()).count(); if (rpc_timeout_ms_ > 0) { Clock::time_point deadline = now + Ms(rpc_timeout_ms_); ctx.set_deadline(deadline); } grpc::Status status = lookup_stub_->Lookup(&ctx, request, response); if (!status.ok()) { failure = true; stats_worker_.record(time_since_epoch, failure, peerAddress(ctx)); return status; } stats_worker_.record(time_since_epoch, failure, response->serverid()); return status; }
编译错误信息
In file included from ~/.local/include/grpc++/grpc++.h:26: In file included from ~/.local/include/grpcpp/grpcpp.h:53: In file included from ~/.local/include/grpcpp/client_context.h:37: ~/.local/include/grpcpp/impl/codegen/client_context.h:275:24: error: call to deleted constructor of 'grpc::TimePoint<time_point<steady_clock, duration<long long, ratio<1, 1000000000>>>>' grpc::TimePoint<T> deadline_tp(deadline); ^ ~~~~~~~~ ~/dev/cpp/grpc/lookupv2/lookup.cc:104:17: note: in instantiation of function template specialization 'grpc::ClientContext::set_deadline<std::chrono::time_point<std::chrono::steady_clock, std::chrono::duration<long long, std::ratio<1, 1000000000>>>>' requested here ctx.set_deadline(deadline); ~/.local/include/grpcpp/impl/codegen/time.h:48:3: note: 'TimePoint' has been explicitly marked deleted here TimePoint(const T& /*time*/) = delete; In file included from ~/.local/include/grpc++/grpc++.h:26: In file included from ~/.local/include/grpcpp/grpcpp.h:53: In file included from ~/.local/include/grpcpp/client_context.h:37: ~/.local/include/grpcpp/impl/codegen/client_context.h:276:29: error: attempt to use a deleted function deadline_ = deadline_tp.raw_time(); ^ ~/.local/include/grpcpp/impl/codegen/time.h:49:16: note: 'raw_time' has been explicitly marked deleted here gpr_timespec raw_time() = delete;
解决方法
原因分析
你使用的GRPC版本中,ClientContext::set_deadline的模板实现已移除对直接传入std::chrono::steady_clock类型time_point的支持,内部依赖的grpc::TimePoint构造函数和raw_time方法被显式删除,导致无法完成类型转换。
方案一:改用相对超时(推荐)
直接使用set_timeout方法设置相对超时时间,无需手动计算deadline,GRPC内部会自动处理当前时间加超时的逻辑:
if (rpc_timeout_ms_ > 0) { ctx.set_timeout(std::chrono::milliseconds(rpc_timeout_ms_)); }
方案二:转换为gpr_timespec类型传入
如果必须使用绝对deadline,手动将std::chrono的time_point转换为GRPC原生的gpr_timespec类型,再调用set_deadline的对应重载:
#include <grpcpp/impl/codegen/time.h> // ... if (rpc_timeout_ms_ > 0) { Clock::time_point deadline = now + Ms(rpc_timeout_ms_); gpr_timespec gpr_deadline = grpc::chrono_steady_clock_to_gpr_time(deadline, GPR_CLOCK_REALTIME); ctx.set_deadline(gpr_deadline); }
注意:如果你的
Clock是std::chrono::system_clock,则使用grpc::chrono_system_clock_to_gpr_time函数。
方案三:替换时间类型为system_clock
部分GRPC版本仅支持std::chrono::system_clock的time_point传入set_deadline,可以修改Clock的定义:
using Clock = std::chrono::system_clock;
内容的提问来源于stack exchange,提问作者amlwwalker
相关产品推荐
相关产品推荐

