thrift 源码剖析1 :TProcessor

本文深入剖析Thrift的TProcessor层,解释其如何与Handler协同工作。Handler作为应用层,通常只需实现服务逻辑。Processor通过调用逻辑流,根据RPC传递的函数名在ProcessMap中查找并执行对应方法,执行业务处理并返回结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TProcessor

  这层主要负责应用层也就是需要我们平常自己实现的一层,它里面封装了Handler类。一般thrift 生成的代码中我们只需要负责写Handler类的逻辑即可,Handler中的逻辑就是我们自己定义的服务逻辑。

分析 demo
Service Serv {
    string  put(1:i32 value) ,
}
Handler

在这里插入图片描述
在这里插入图片描述
  可以看到Handler 类继承了ServIf 类,thrift 是通过c++中Base类指针可以指向Dervied类对象,从而实现通过 Processor来操作我们自己实现的Handler类。

Processor
thrift 内部文件代码:
class TProcessorEventHandler {
public:
  virtual ~TProcessorEventHandler() {}

  /**
   * Called before calling other callback methods.
   * Expected to return some sort of context object.
   * The return value is passed to all other callbacks
   * for that function invocation.
   */
  virtual void* getContext(const char* fn_name, void* serverContext) {
    (void)fn_name;
    (void)serverContext;
    return NULL;
  }

  /**
   * Expected to free resources associated with a context.
   */
  virtual void freeContext(void* ctx, const char* fn_name) {
    (void)ctx;
    (void)fn_name;
  }

  /**
   * Called before reading arguments.
   */
  virtual void preRead(void* ctx, const char* fn_name) {
    (void)ctx;
    (void)fn_name;
  }

  /**
   * Called between reading arguments and calling the handler.
   */
  virtual void postRead(void* ctx, const char* fn_name, uint32_t bytes) {
    (void)ctx;
    (void)fn_name;
    (void)bytes;
  }

  /**
   * Called between calling the handler and writing the response.
   */
  virtual void preWrite(void* ctx, const char* fn_name) {
    (void)ctx;
    (void)fn_name;
  }

  /**
   * Called after writing the response.
   */
  virtual void postWrite(void* ctx, const char* fn_name, uint32_t bytes) {
    (void)ctx;
    (void)fn_name;
    (void)bytes;
  }

  /**
   * Called when an async function call completes successfully.
   */
  virtual void asyncComplete(void* ctx, const char* fn_name) {
    (void)ctx;
    (void)fn_name;
  }

  /**
   * Called if the handler throws an undeclared exception.
   */
  virtual void handlerError(void* ctx, const char* fn_name) {
    (void)ctx;
    (void)fn_name;
  }

protected:
  TProcessorEventHandler() {}
};
class TProcessor {
public:
  virtual ~TProcessor() {}

  virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
                       boost::shared_ptr<protocol::TProtocol> out,
                       void* connectionContext) = 0;

  bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> io, void* connectionContext) {
    return process(io, io, connectionContext);
  }

  boost::shared_ptr<TProcessorEventHandler> getEventHandler() { return eventHandler_; }

  void setEventHandler(boost::shared_ptr<TProcessorEventHandler> eventHandler) {
    eventHandler_ = eventHandler;
  }

protected:
  TProcessor() {}

  boost::shared_ptr<TProcessorEventHandler> eventHandler_;
};

class TDispatchProcessor : public TProcessor {
public:
  virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
                       boost::shared_ptr<protocol::TProtocol> out,
                       void* connectionContext) {
    std::string fname;
    protocol::TMessageType mtype;
    int32_t seqid;
    in->readMessageBegin(fname, mtype, seqid);

    if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
      GlobalOutput.printf("received invalid message type %d from client", mtype);
      return false;
    }

    return dispatchCall(in.get(), out.get(), fname, seqid, connectionContext);
  }
protected:
  virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in,
                            apache::thrift::protocol::TProtocol* out,
                            const std::string& fname,
                            int32_t seqid,
                            void* callContext) = 0;
};

业务生成代码:

class ServProcessor : public ::apache::thrift::TDispatchProcessor {
 protected:
  boost::shared_ptr<ServIf> iface_;
  virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, 
      ::apache::thrift::protocol::TProtocol* oprot, 
      const std::string& fname, int32_t seqid, void* callContext);
 private:
  typedef  void (ServProcessor::*ProcessFunction)(int32_t,
   ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
  
  typedef std::map<std::string, ProcessFunction> ProcessMap;
  ProcessMap processMap_;
  
  void process_put(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, 
  ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
 public:
  ServProcessor(boost::shared_ptr<ServIf> iface) :
    iface_(iface) {
    processMap_["put"] = &ServProcessor::process_put; //这个put是我们Service中的函数名
  }

  virtual ~ServProcessor() {}
};

bool ServProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, 
::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, 
void* callContext) {
  ProcessMap::iterator pfn;
  pfn = processMap_.find(fname);
  if (pfn == processMap_.end()) {
    iprot->skip(::apache::thrift::protocol::T_STRUCT);
    iprot->readMessageEnd();
    iprot->getTransport()->readEnd();
    ::apache::thrift::TApplicationException x(::apache::thrift::
    TApplicationException::UNKNOWN_METHOD, 
    "Invalid method name: '"+fname+"'");
    oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return true;
  }
  (this->*(pfn->second))(seqid, iprot, oprot, callContext); //Processor::process_put 
  return true;
}
void ServProcessor::process_put(int32_t seqid, ::apache::thrift::protocol::TProtocol*
 iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = NULL;
  if (this->eventHandler_.get() != NULL) {
    ctx = this->eventHandler_->getContext("Serv.put", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Serv.put");

  if (this->eventHandler_.get() != NULL) {
    this->eventHandler_->preRead(ctx, "Serv.put");
  }

  Serv_put_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != NULL) {
    this->eventHandler_->postRead(ctx, "Serv.put", bytes);
  }

  Serv_put_result result;
  try {
    iface_->put(result.success, args.value); //这里调用了我们自己设置的逻辑函数
    result.__isset.success = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != NULL) {
      this->eventHandler_->handlerError(ctx, "Serv.put");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("put", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != NULL) {
    this->eventHandler_->preWrite(ctx, "Serv.put");
  }

  oprot->writeMessageBegin("put", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot); //返回结果
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != NULL) {
    this->eventHandler_->postWrite(ctx, "Serv.put", bytes);
  }
}
调用逻辑流
TDispatchProcessor::processor -> ServProcessor::dispatchCall -> ServProcessor::process_put 
--> Handler::put 

  从上面的源码可以看出ServProcessor::ProcessMap 主要用来查找方法的,当client发起相应RPC时,RPC会把相应函数的名字传过去,Server收到函数后就在ProcessMap查找是否有相应函数名的函数,有使用相应函数指针去调用函数,随后会调用相应的业务函数去进行业务处理然后把结果返回回去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值