baidu / sofa-pbrpc

A light-weight RPC implement of google protobuf RPC framework.
Other
2.13k stars 655 forks source link

增加Cancel支持 #85

Open qinzuoyan opened 8 years ago

qinzuoyan commented 8 years ago

背景

这里说的Cancel是指Client可以主动取消request的执行,包括在request还没有通过网络发送时取消发送,或者将Cancel命令通过网络传递到server端以提前终止服务的执行(在server端的服务实现支持Cancel功能的情况下),其目的都是避免不必要的资源消耗,无论是网络资源还是计算资源。

protobuf的RPC框架中定义了Cancel功能的接口和语义,具体在RpcController类中进行了定义:

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

考虑server端用户是如何使用cancel功能的:在用户实现的服务处理函数开始时,通过RpcController::NotifyOnCancel()注册一个Closure回调函数,回调函数的处理逻辑是提前终止服务处理,避免不必要的资源消耗。

实现

考虑的一种实现方案是:在client端调用RpcController::StartCancel的时候,发送一个special的cancel_request到server端,server收到cancel_request后,找到这个request对应的RpcController,然后调用服务实现者通过RpcController::NotifyOnCancel()注册的回调函数。