// Client-side methods ---------------------------------------------
// Advises the RPC system that the caller desires that the RPC call be
// canceled. The RPC system may cancel it immediately, may wait awhile and
// then cancel it, or may not even cancel the call at all. If the call is
// canceled, the "done" callback will still be called and the RpcController
// will indicate that the call failed at that time.
virtual void StartCancel() = 0;
// Server-side methods ---------------------------------------------
// If true, indicates that the client canceled the RPC, so the server may
// as well give up on replying to it. The server should still call the
// final "done" callback.
virtual bool IsCanceled() const = 0;
// Asks that the given callback be called when the RPC is canceled. The
// callback will always be called exactly once. If the RPC completes without
// being canceled, the callback will be called after completion. If the RPC
// has already been canceled when NotifyOnCancel() is called, the callback
// will be called immediately.
//
// NotifyOnCancel() must be called no more than once per request.
virtual void NotifyOnCancel(Closure* callback) = 0;
背景
这里说的Cancel是指Client可以主动取消request的执行,包括在request还没有通过网络发送时取消发送,或者将Cancel命令通过网络传递到server端以提前终止服务的执行(在server端的服务实现支持Cancel功能的情况下),其目的都是避免不必要的资源消耗,无论是网络资源还是计算资源。
protobuf的RPC框架中定义了Cancel功能的接口和语义,具体在RpcController类中进行了定义:
考虑server端用户是如何使用cancel功能的:在用户实现的服务处理函数开始时,通过RpcController::NotifyOnCancel()注册一个Closure回调函数,回调函数的处理逻辑是提前终止服务处理,避免不必要的资源消耗。
实现
考虑的一种实现方案是:在client端调用RpcController::StartCancel的时候,发送一个special的cancel_request到server端,server收到cancel_request后,找到这个request对应的RpcController,然后调用服务实现者通过RpcController::NotifyOnCancel()注册的回调函数。