美文网首页
Thrift架构及源码解读

Thrift架构及源码解读

作者: 井地儿 | 来源:发表于2019-12-18 23:18 被阅读0次

    1 Thrift基本用法

    ## 1,搭建thrift编译环境
    ## 2,定义thrift接口文件
    ## 3,编译接口文件生成源代码
    ## 4,编写接口的实现类
    ### 4.1 实现Iface接口
    ## 5,编写服务端并启动服务
    ### 5.1 定义server模式(TServer)
    ### 5.2 定义传输层transport(TServerTransport)
    ### 5.3 定义协议层protocol(TProtocolFactory)
    ### 5.4 定义请求处理器processor(TProcessor)
    ### 5.5 启动服务
    ## 6,编写客户端并远程调用(客户端传输层和协议层需和服务端保持一致)
    ### 6.1 定义传输层transport(TTransport)
    ### 6.2 定义协议层protocal(TTransport)
    ### 6.3 定义客户端对象client(Client)
    ### 6.4 开启连接open
    ### 6.5 客户端远程调用
    ### 6.6 关闭连接close
    

    1.1 搭建thrift编译环境

    1.1.1 tar包下载

    http://www.apache.org/dyn/closer.cgi?path=/thrift/0.13.0/thrift-0.13.0.tar.gz

    1.1.2 Manven依赖

    <dependency>
      <groupId>org.apache.thrift</groupId>
      <artifactId>libthrift</artifactId>
      <version>0.13.0</version>
    </dependency>
    

    1.1.3 构建并安装thrift编译器

    官网参考:https://thrift.apache.org/docs/install

    1.2 定义thrift接口文件

    thrift接口定义文件IDL通常是以.thrift后缀结尾。

    命名空间:相当于Java中的包。格式:namespace 语言 命名空间名称 例:

    namespace java org.apache.hive.service.cli.thrift
    接口:生成的接口文件名。格式:service ServerName { ... }

    IDL中支持8种基本类型:string,i16,i32,i64,byte,bool,double,void;三种复杂类型map,set,list;还支持自定义数据类型:enum(枚举),const(常量)和struct(结构体)。

    另外还支持对类型重定义(相当于定义变量):typedef i32 Myi32

    接口定义示例

    SayHello.thrift

    // 命名空间
    namespace java org.jeff.demo.thrift
     
    // 枚举
    enum SayHelloVersion{
        V1
        V2
        V3
        V4
    }
     
    // 常量
    const set<SayHelloVersion> VERSIONS = [
        SayHelloVersion.V1
        SayHelloVersion.V2
        SayHelloVersion.V3
        SayHelloVersion.V4
    ]
     
    // 类型重定义
    typedef i32 Myi32Type
     
    // 联合
    union MyUnion{
        1:optional string stringValue,
        2:optional Myi32Type i32Value
    }
     
    // 结构体(成员变量分割可以是逗号也可以是分号)
    struct SayHelloResp{
        1:required string msg
    }
     
    // required: 必选字段
    // optional: 可选字段
    struct SayHelloReq{
        1:required string username,
        2:optional i32 age
    }
     
    struct SayByeReq{
        1:required string username,
        2:optional i32 age
    }
     
     
    // 服务定义
    service HelloThriftServer{
        SayHelloResp SayHello(1:SayHelloReq req);
        void SayBye(1:SayByeReq req)
    }
    

    1.3 编译接口文件生成源代码

    编译语法

    thrift --gen <language> <Thrift filename>

    编译后的源码中主要有如下几个重要的类:(其中Iface,Client,Processor是核心类)

    Iface:同步接口类。真实的业务逻辑类实现了该接口。

    Client:同步客户端类,实现了Iface接口。

    Processor:请求处理代理类。内部map中保存了所有的接口函数名和函数对象的映射。这里处理请求,通过代理调用真实的业务逻辑方法,并返回结果。包括请求的反序列化和返回值的序列化。

    AsyncIface:异步接口类(不常用)。

    AsyncClient:异步客户端类(不常用)。

    函数类:在Processor中所有的接口函数都定义成了类。例:

    public static class SayHello<I extends Iface> extends org.apache.thrift.ProcessFunction<I, SayHello_args>
    参数类:命名规则: 函数名 + “_args”, 例:OpenSession_args

    返回值类:命名规则:函数名 + “_result”, 例: OpenSession_result

    thrift编译生成的源代码中函数名都是硬编码,并不是通过反射的方式调用的,很小的接口文件(50行)编译后的源代码都会很大(1700+ 行),相对而言比较重。

    thrift编译生成源代码示例

    thrift --gen java:beans SayHello.thrift


    image.png

    源代码见附件。

    1.4 编写接口实现类

    接口实现类需要实现Iface接口。

    ## 1,实现Iface接口
    

    接口实现类示例

    package org.jeff.demo.thrift;
     
    import org.apache.thrift.TException;
     
    /**
     * @author stefan 2019/12/18
     */
    public class HelloServerImpl implements HelloThriftServer.Iface {
      @Override public SayHelloResp SayHello(SayHelloReq req) throws TException {
        String username = req.getUsername();
        int age = req.getAge();
        SayHelloResp resp = new SayHelloResp();
        resp.setMsg("Hello, i am " + username + ", i am " + age + " years old.");
        return resp;
      }
     
      @Override public void SayBye(SayByeReq req) throws TException {
        String username = req.getUsername();
        int age = req.getAge();
        System.out.println("Goodbye " + username +", see you...");
      }
    }
    
    

    1.5 编写服务端并启用服务

    ## 5,编写服务端并启动服务
    ### 5.1 定义server模式(TServer)
    ### 5.2 定义传输层transport(TServerTransport)
    ### 5.3 定义协议层protocol(TProtocolFactory)
    ### 5.4 定义请求处理器processor(TProcessor)
    ### 5.5 启动服务
    

    服务端实现示例

    package org.jeff.demo.thrift;
     
    import org.apache.thrift.TProcessor;
    import org.apache.thrift.protocol.TBinaryProtocol;
    import org.apache.thrift.server.TServer;
    import org.apache.thrift.server.TThreadPoolServer;
    import org.apache.thrift.transport.TServerSocket;
    import org.apache.thrift.transport.TTransportException;
    import org.apache.thrift.transport.TTransportFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
     
    import java.util.concurrent.*;
     
    /**
     * @author stefan 2019/12/18
     */
    public class MainServer {
      public static final Logger LOG = LoggerFactory.getLogger(MainServer.class);
      private static int thrift_port = 8890;
      private static HelloServerImpl service = new HelloServerImpl();
      private static TServer server;
     
      public static void main(String[] args){
        if(!start()){
          System.exit(0);
        }
      }
     
      public static void createServer(){
        try {
          // Server thread pool
          String threadPoolName = "HelloServer-Handler-Pool";
          int minWorkerThreads = 10;
          int maxWorkerThreads = 100;
          int workerKeepAliveTime = 100;
     
          ExecutorService executorService = new ThreadPoolExecutor(minWorkerThreads, maxWorkerThreads,
              workerKeepAliveTime, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
              new ThreadFactoryWithGarbageCleanup(threadPoolName));
          TProcessor processor = new HelloThriftServer.Processor<>(service);
          TServerSocket serverSocket = new TServerSocket(thrift_port);
          TThreadPoolServer.Args sargs = new TThreadPoolServer.Args(serverSocket)
              .processor(processor)
              .transportFactory(new TTransportFactory())
              .protocolFactory(new TBinaryProtocol.Factory())
              .inputProtocolFactory(new TBinaryProtocol.Factory(true, true, 1000000, 1000000))
              .requestTimeout(1000).requestTimeoutUnit(TimeUnit.SECONDS)
              .beBackoffSlotLength(1000).beBackoffSlotLengthUnit(TimeUnit.MILLISECONDS)
              .executorService(executorService);
          server = new TThreadPoolServer(sargs);
        } catch (TTransportException e) {
          e.printStackTrace();
          System.out.println("");
          System.exit(1);
        }
      }
     
      public static boolean start(){
        try{
          createServer();
          LOG.info("Starting service " + server.getClass().getName() + " on port: " + thrift_port);
          server.serve();
        }catch(Exception ex){
          LOG.error("Starting service failed...",ex);
          return false;
        }
        return true;
      }
    }
     
    class ThreadFactoryWithGarbageCleanup implements ThreadFactory {
      private final String namePrefix;
      public ThreadFactoryWithGarbageCleanup(String threadPoolName){
        namePrefix = threadPoolName;
      }
     
      @Override public Thread newThread(Runnable r) {
        Thread newThread = new ThreadWithGarbageCleanup(r);
        newThread.setName(namePrefix + ":Thread-" + newThread.getId());
        return newThread;
      }
    }
     
    class ThreadWithGarbageCleanup extends Thread {
      public static final Logger LOG = LoggerFactory.getLogger(ThreadWithGarbageCleanup.class);
      public ThreadWithGarbageCleanup(){}
      public ThreadWithGarbageCleanup(Runnable runnable){
        super(runnable);
      }
      @Override protected void finalize() throws Throwable {
        LOG.info("cleanUp...");
        super.finalize();
      }
    }
    

    1.6 编写客户端并远程调用

    ## 6,编写客户端并远程调用(客户端传输层和协议层需和服务端保持一致)
    ### 6.1 定义传输层transport(TTransport)
    ### 6.2 定义协议层protocal(TTransport)
    ### 6.3 定义客户端对象client(Client)
    ### 6.4 开启连接open
    ### 6.5 客户端远程调用
    ### 6.6 关闭连接close
    

    客户端实现示例

    package org.jeff.demo.thrift;
     
    import org.apache.thrift.TException;
    import org.apache.thrift.protocol.TBinaryProtocol;
    import org.apache.thrift.transport.TSocket;
     
    /**
     * @author stefan 2019/12/18
     */
    public class MainClient {
      private static String THRIFT_HOST = "localhost";
      private static int THRIFT_PORT = 8890;
     
      public static void main(String[] args) throws TException {
        TSocket socket = new TSocket(THRIFT_HOST, THRIFT_PORT);
        TBinaryProtocol protocol = new TBinaryProtocol(socket);
        socket.open();
        HelloThriftServer.Client client = new HelloThriftServer.Client(protocol);
        SayHelloReq req = new SayHelloReq();
        req.setUsername("jeff");
        req.setAge(18);
        SayHelloResp resp = client.SayHello(req);
        System.out.println(resp.getMsg());
        socket.close();
      }
    }
    

    2 Thrift原理及源码解读

    2.1 架构原理

    RPC,远程过程调用,即实现远端函数之间的调用,区别于本地函数调用。

    Thrift是Facebook开源的一款跨语言服务部署框架,通过TDL语言定义RPC接口,并由thrift编译生成不同语言的源代码,实现RPC底层通信需要的传输层,协议层等。

    架构原理图

    image.png

    Thrift框架提供了多种server服务模式,多种transport传输方式,多种protocal协议。

    2.2 server服务模式

    所有的服务模式都是TServer抽象类的子类,继承关系如下:

    image.png

    TServer定义了server抽象方法,需要子类实现:

    /**
     * The run method fires up the server and gets things going.
     */
    public abstract void serve();
    

    所有的入口都是server方法。

    2.2.1 TSimpleServer

    1)简介:

    /**
     * Simple singlethreaded server for testing.
     *
     */
    public class TSimpleServer extends TServer {
    

    单线程的用于测试的服务模式,不适用于生产。

    2)源码解读:

    执行流程:

    // 1, 启动一个监听器
    // 2, 如果没有stop,则循环接收一个请求,并进行处理
    // 3, 如果stop,则退出
    

    附源码实现:

    public void serve() {
      try {
        serverTransport_.listen();
      } catch (TTransportException ttx) {
        LOGGER.error("Error occurred during listening.", ttx);
        return;
      }
     
      // Run the preServe event
      if (eventHandler_ != null) {
        eventHandler_.preServe();
      }
     
      setServing(true);
     
      while (!stopped_) {
        TTransport client = null;
        TProcessor processor = null;
        TTransport inputTransport = null;
        TTransport outputTransport = null;
        TProtocol inputProtocol = null;
        TProtocol outputProtocol = null;
        ServerContext connectionContext = null;
        try {
          client = serverTransport_.accept();
          if (client != null) {
            processor = processorFactory_.getProcessor(client);
            inputTransport = inputTransportFactory_.getTransport(client);
            outputTransport = outputTransportFactory_.getTransport(client);
            inputProtocol = inputProtocolFactory_.getProtocol(inputTransport);
            outputProtocol = outputProtocolFactory_.getProtocol(outputTransport);
            if (eventHandler_ != null) {
              connectionContext = eventHandler_.createContext(inputProtocol, outputProtocol);
            }
            while (true) {
              if (eventHandler_ != null) {
                eventHandler_.processContext(connectionContext, inputTransport, outputTransport);
              }
              if(!processor.process(inputProtocol, outputProtocol)) {
                break;
              }
            }
          }
        } catch (TTransportException ttx) {
          // Client died, just move on
        } catch (TException tx) {
          if (!stopped_) {
            LOGGER.error("Thrift error occurred during processing of message.", tx);
          }
        } catch (Exception x) {
          if (!stopped_) {
            LOGGER.error("Error occurred during processing of message.", x);
          }
        }
     
        if (eventHandler_ != null) {
          eventHandler_.deleteContext(connectionContext, inputProtocol, outputProtocol);
        }
     
        if (inputTransport != null) {
          inputTransport.close();
        }
     
        if (outputTransport != null) {
          outputTransport.close();
        }
     
      }
      setServing(false);
    }
    

    2.2.2 TThreadPoolServer

    1)简介:

    /**
     * Server which uses Java's built in ThreadPool management to spawn off
     * a worker pool that
     *
     */
    public class TThreadPoolServer extends TServer {
    

    采用java线程池管理的多线程服务,多用于生产环境。Hive源码中的Thrift采用的便是这种模式。

    适用场景:可以有效预估并发量的情况下,可以合理设置线程池大小,提高处理并发请求效率。

    2)源码解读:

    采用主线程只负责接收请求,线程池负责处理请求;优点是可以及时响应并发用户请求;在线程池大小内提高效率,在并发请求超过线程池大小时,会阻塞。

    执行流程:

    // 1, 启动监听器
    // 2, 循环接收请求,每接收一个请求,交给线程池执行
    // 3, 停止
    

    server入口,比较简单,主要调用了三个方法:preServer,execute,waitForShutDown

    public void serve() {
     if (!preServe()) {
      return;
     }
     
     execute();
     waitForShutdown();
       
      setServing(false);
    }
    

    preServer():在这里主要负责启动了一个监听器。

    protected boolean preServe() {
     try {
        serverTransport_.listen();
      } catch (TTransportException ttx) {
        LOGGER.error("Error occurred during listening.", ttx);
        return false;
      }
     
      // Run the preServe event
      if (eventHandler_ != null) {
        eventHandler_.preServe();
      }
      stopped_ = false;
      setServing(true);
       
      return true;
    }
    

    execute():这里每接收到一个请求,创建一个独立的线程,交给线程池执行。

    protected void execute() {
      int failureCount = 0;
      while (!stopped_) {
        try {
          TTransport client = serverTransport_.accept();
          WorkerProcess wp = new WorkerProcess(client);
     
          int retryCount = 0;
          long remainTimeInMillis = requestTimeoutUnit.toMillis(requestTimeout);
          while(true) {
            try {
              executorService_.execute(wp);
              break;
            } catch(Throwable t) {
              if (t instanceof RejectedExecutionException) {
                retryCount++;
                try {
                  if (remainTimeInMillis > 0) {
                    //do a truncated 20 binary exponential backoff sleep
                    long sleepTimeInMillis = ((long) (random.nextDouble() *
                        (1L << Math.min(retryCount, 20)))) * beBackoffSlotInMillis;
                    sleepTimeInMillis = Math.min(sleepTimeInMillis, remainTimeInMillis);
                    TimeUnit.MILLISECONDS.sleep(sleepTimeInMillis);
                    remainTimeInMillis = remainTimeInMillis - sleepTimeInMillis;
                  } else {
                    client.close();
                    wp = null;
                    LOGGER.warn("Task has been rejected by ExecutorService " + retryCount
                        + " times till timedout, reason: " + t);
                    break;
                  }
                } catch (InterruptedException e) {
                  LOGGER.warn("Interrupted while waiting to place client on executor queue.");
                  Thread.currentThread().interrupt();
                  break;
                }
              } else if (t instanceof Error) {
                LOGGER.error("ExecutorService threw error: " + t, t);
                throw (Error)t;
              } else {
                //for other possible runtime errors from ExecutorService, should also not kill serve
                LOGGER.warn("ExecutorService threw error: " + t, t);
                break;
              }
            }
          }
        } catch (TTransportException ttx) {
          if (!stopped_) {
            ++failureCount;
            LOGGER.warn("Transport error occurred during acceptance of message.", ttx);
          }
        }
      }
    }
    

    waitForShutDown:这里比较简单,就是调用了线程池的shutDown方法。

    protected void waitForShutdown() {
     executorService_.shutdown();
     
      // Loop until awaitTermination finally does return without a interrupted
      // exception. If we don't do this, then we'll shut down prematurely. We want
      // to let the executorService clear it's task queue, closing client sockets
      // appropriately.
      long timeoutMS = stopTimeoutUnit.toMillis(stopTimeoutVal);
      long now = System.currentTimeMillis();
      while (timeoutMS >= 0) {
        try {
          executorService_.awaitTermination(timeoutMS, TimeUnit.MILLISECONDS);
          break;
        } catch (InterruptedException ix) {
          long newnow = System.currentTimeMillis();
          timeoutMS -= (newnow - now);
          now = newnow;
        }
      }
    }
    

    2.2.3 AbstractNonblockingServer

    1)简介

    /**
     * Provides common methods and classes used by nonblocking TServer
     * implementations.
     */
    public abstract class AbstractNonblockingServer extends TServer {
    

    非阻塞服务的抽象类,有三个子类实现:

    image.png

    service逻辑:子类主要重写了startThreads方法。

    /**
     * Begin accepting connections and processing invocations.
     */
    public void serve() {
      // start any IO threads
      if (!startThreads()) {
        return;
      }
     
      // start listening, or exit
      if (!startListening()) {
        return;
      }
     
      setServing(true);
     
      // this will block while we serve
      waitForShutdown();
     
      setServing(false);
     
      // do a little cleanup
      stopListening();
    }
    

    2.2.4 TThreadedSelectorServer

    1)简介

    /**
     * A Half-Sync/Half-Async server with a separate pool of threads to handle
     * non-blocking I/O. Accepts are handled on a single thread, and a configurable
     * number of nonblocking selector threads manage reading and writing of client
     * connections. A synchronous worker thread pool handles processing of requests.
     *
     * Performs better than TNonblockingServer/THsHaServer in multi-core
     * environments when the the bottleneck is CPU on the single selector thread
     * handling I/O. In addition, because the accept handling is decoupled from
     * reads/writes and invocation, the server has better ability to handle back-
     * pressure from new connections (e.g. stop accepting when busy).
     *
     * Like TNonblockingServer, it relies on the use of TFramedTransport.
     */
    public class TThreadedSelectorServer extends AbstractNonblockingServer {
    

    半同步半异步服务器,用一个独立的线程池来处理非阻塞I/O。接收请求用单独的一个线程来处理,并且通过可配置数量的非阻塞选择器线程管理客户端连接的读写。一个同步的工作线程池处理处理中的请求。

    当单个选择器线程上的瓶颈是CPU处理I/O时,在多核环境中,性能要优于TNonblockingServer/THsHaServer。另外,因为接受处理请求和读写以及调用时隔离的,服务器便有更好的能力来处理来自新连接的压力(比如当繁忙的时候停止接受请求)。

    和TNonblockingServer一样,它依赖于TFramedTransport的使用。

    优点:性能最好的服务器模式。

    2)源码解读

    // 1,初始化一组选择线程用于处理业务(数量可配置)。我们称作工作线程
    // 2,初始化一个选择线程负载均衡器,并将工作线程注册到负载均衡器中。
    // 3,初始化一个请求接受线程,并将选择线程负载均衡器注册到处理请求的线程中。我们称作接收线程。
    // 4,启动所有的工作线程。
    // 5,启动接收线程,接收请求。
    

    主线程:

    @Override
    protected boolean startThreads() {
      try {
        for (int i = 0; i < args.selectorThreads; ++i) {
          selectorThreads.add(new SelectorThread(args.acceptQueueSizePerThread));
        }
        acceptThread = new AcceptThread((TNonblockingServerTransport) serverTransport_,
          createSelectorThreadLoadBalancer(selectorThreads));
        for (SelectorThread thread : selectorThreads) {
          thread.start();
        }
        acceptThread.start();
        return true;
      } catch (IOException e) {
        LOGGER.error("Failed to start threads!", e);
        return false;
      }
    }
    

    acceptThread:这里调用了select()方法。

    /**
     * The work loop. Selects on the server transport and accepts. If there was
     * a server transport that had blocking accepts, and returned on blocking
     * client transports, that should be used instead
     */
    public void run() {
      try {
        if (eventHandler_ != null) {
          eventHandler_.preServe();
        }
     
        while (!stopped_) {
          select();
        }
      } catch (Throwable t) {
        LOGGER.error("run() on AcceptThread exiting due to uncaught error", t);
      } finally {
        try {
          acceptSelector.close();
        } catch (IOException e) {
          LOGGER.error("Got an IOException while closing accept selector!", e);
        }
        // This will wake up the selector threads
        TThreadedSelectorServer.this.stop();
      }
    }
    

    select方法:在select方法里监听请求,并且通过 handleAccept 方法处理请求。

    /**
     * Select and process IO events appropriately: If there are connections to
     * be accepted, accept them.
     */
    private void select() {
      try {
        // wait for connect events.
        acceptSelector.select();
     
        // process the io events we received
        Iterator<SelectionKey> selectedKeys = acceptSelector.selectedKeys().iterator();
        while (!stopped_ && selectedKeys.hasNext()) {
          SelectionKey key = selectedKeys.next();
          selectedKeys.remove();
     
          // skip if not valid
          if (!key.isValid()) {
            continue;
          }
     
          if (key.isAcceptable()) {
            handleAccept();
          } else {
            LOGGER.warn("Unexpected state in select! " + key.interestOps());
          }
        }
      } catch (IOException e) {
        LOGGER.warn("Got an IOException while selecting!", e);
      }
    }
    

    handleAccept方法:

    // 1,负载均衡器选择一个选择线程(这里的负载均衡器策略是轮训策略)
    // 2,请求策略是FAST_ACCEPT或线程池ExecutorService为空,则立即处理。(策略有两种:FAIR_ACCEPT 和 FAST_ACCEPT)
    // 3,否则,交给ExecutorService公平处理。
    
    /**
     * Accept a new connection.
     */
    private void handleAccept() {
      final TNonblockingTransport client = doAccept();
      if (client != null) {
        // Pass this connection to a selector thread
        final SelectorThread targetThread = threadChooser.nextThread();
     
        if (args.acceptPolicy == Args.AcceptPolicy.FAST_ACCEPT || invoker == null) {
          doAddAccept(targetThread, client);
        } else {
          // FAIR_ACCEPT
          try {
            invoker.submit(new Runnable() {
              public void run() {
                doAddAccept(targetThread, client);
              }
            });
          } catch (RejectedExecutionException rx) {
            LOGGER.warn("ExecutorService rejected accept registration!", rx);
            // close immediately
            client.close();
          }
        }
      }
    }
    

    2.2.5 TNonblockingServer

    1)简介

    /**
     * A nonblocking TServer implementation. This allows for fairness amongst all
     * connected clients in terms of invocations.
     *
     * This server is inherently single-threaded. If you want a limited thread pool
     * coupled with invocation-fairness, see THsHaServer.
     *
     * To use this server, you MUST use a TFramedTransport at the outermost
     * transport, otherwise this server will be unable to determine when a whole
     * method call has been read off the wire. Clients must also use TFramedTransport.
     */
    public class TNonblockingServer extends AbstractNonblockingServer {
    

    非阻塞TServer的接口。允许所有已连接的客户端调用都是公平的。

    这个服务本质上是单线程的。如果你想在有限的线程池中实现公平性,可以参考THsHaServer。

    使用这个服务,你必须在最外层使用TFramedTransport传输协议,否则服务将无法确定何时整个方法调用已经断开。Client端必须使用TFramedTransport传输协议。

    优点:采用选择器实现多个连接的公平调用

    缺点:单线程处理,依然存在瓶颈

    2)源码解读

    /**
     * Start the selector thread to deal with accepts and client messages.
     *
     * @return true if everything went ok, false if we couldn't start for some
     * reason.
     */
    @Override
    protected boolean startThreads() {
      // start the selector
      try {
        selectAcceptThread_ = new SelectAcceptThread((TNonblockingServerTransport)serverTransport_);
        selectAcceptThread_.start();
        return true;
      } catch (IOException e) {
        LOGGER.error("Failed to start selector thread!", e);
        return false;
      }
    }
    
    
    /**
     * The work loop. Handles both selecting (all IO operations) and managing
     * the selection preferences of all existing connections.
     */
    public void run() {
      try {
        if (eventHandler_ != null) {
          eventHandler_.preServe();
        }
     
        while (!stopped_) {
          select();
          processInterestChanges();
        }
        for (SelectionKey selectionKey : selector.keys()) {
          cleanupSelectionKey(selectionKey);
        }
      } catch (Throwable t) {
        LOGGER.error("run() exiting due to uncaught error", t);
      } finally {
        try {
          selector.close();
        } catch (IOException e) {
          LOGGER.error("Got an IOException while closing selector!", e);
        }
        stopped_ = true;
      }
    }
    

    2.2.6 THsHaServer

    1)简介

    /**
     * An extension of the TNonblockingServer to a Half-Sync/Half-Async server.
     * Like TNonblockingServer, it relies on the use of TFramedTransport.
     */
    public class THsHaServer extends TNonblockingServer {
    

    继承于TNonblockingServer的半同步半异步的服务器。

    和TNonblockingServer一扬,依赖于使用TFramedTransport传输协议。

    优点:THsHaServer的产生是为了解决TNonblockingServer单线程的瓶颈,在THsHaServer中采用线程池来处理业务请求。

    缺点:主线程依然还是采用单线程处理请求,在高并发的场景依然存在瓶颈。

    2)源码解读

    重新了requestInvoke方式,使用线程池处理请求。

    /**
     * We override the standard invoke method here to queue the invocation for
     * invoker service instead of immediately invoking. The thread pool takes care
     * of the rest.
     */
    @Override
    protected boolean requestInvoke(FrameBuffer frameBuffer) {
      try {
        Runnable invocation = getRunnable(frameBuffer);
        invoker.execute(invocation);
        return true;
      } catch (RejectedExecutionException rx) {
        LOGGER.warn("ExecutorService rejected execution!", rx);
        return false;
      }
    }
    

    2.3 传输层

    TTransport是所有传输层的基类。定义了传输过程中信息如何读如何写等。

    抽象方法主要有:close,isOpen,open,read,write


    image.png

    基于不同的传输方式,有多种实现。继承关系如下:


    image.png

    未完待续~~~

    附:thrift编译生成的源代码 HelloThriftServer.java

    /**
     * Autogenerated by Thrift Compiler (0.12.0)
     *
     * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
     *  @generated
     */
    package org.jeff.demo.thrift;
    
    @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
    @javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-12-18")
    public class HelloThriftServer {
    
      public interface Iface {
    
        public SayHelloResp SayHello(SayHelloReq req) throws org.apache.thrift.TException;
    
        public void SayBye(SayByeReq req) throws org.apache.thrift.TException;
    
      }
    
      public interface AsyncIface {
    
        public void SayHello(SayHelloReq req, org.apache.thrift.async.AsyncMethodCallback<SayHelloResp> resultHandler) throws org.apache.thrift.TException;
    
        public void SayBye(SayByeReq req, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
    
      }
    
      public static class Client extends org.apache.thrift.TServiceClient implements Iface {
        public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
          public Factory() {}
          public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
            return new Client(prot);
          }
          public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
            return new Client(iprot, oprot);
          }
        }
    
        public Client(org.apache.thrift.protocol.TProtocol prot)
        {
          super(prot, prot);
        }
    
        public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
          super(iprot, oprot);
        }
    
        public SayHelloResp SayHello(SayHelloReq req) throws org.apache.thrift.TException
        {
          send_SayHello(req);
          return recv_SayHello();
        }
    
        public void send_SayHello(SayHelloReq req) throws org.apache.thrift.TException
        {
          SayHello_args args = new SayHello_args();
          args.setReq(req);
          sendBase("SayHello", args);
        }
    
        public SayHelloResp recv_SayHello() throws org.apache.thrift.TException
        {
          SayHello_result result = new SayHello_result();
          receiveBase(result, "SayHello");
          if (result.isSetSuccess()) {
            return result.success;
          }
          throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "SayHello failed: unknown result");
        }
    
        public void SayBye(SayByeReq req) throws org.apache.thrift.TException
        {
          send_SayBye(req);
          recv_SayBye();
        }
    
        public void send_SayBye(SayByeReq req) throws org.apache.thrift.TException
        {
          SayBye_args args = new SayBye_args();
          args.setReq(req);
          sendBase("SayBye", args);
        }
    
        public void recv_SayBye() throws org.apache.thrift.TException
        {
          SayBye_result result = new SayBye_result();
          receiveBase(result, "SayBye");
          return;
        }
    
      }
      public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
        public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
          private org.apache.thrift.async.TAsyncClientManager clientManager;
          private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
          public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
            this.clientManager = clientManager;
            this.protocolFactory = protocolFactory;
          }
          public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
            return new AsyncClient(protocolFactory, clientManager, transport);
          }
        }
    
        public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
          super(protocolFactory, clientManager, transport);
        }
    
        public void SayHello(SayHelloReq req, org.apache.thrift.async.AsyncMethodCallback<SayHelloResp> resultHandler) throws org.apache.thrift.TException {
          checkReady();
          SayHello_call method_call = new SayHello_call(req, resultHandler, this, ___protocolFactory, ___transport);
          this.___currentMethod = method_call;
          ___manager.call(method_call);
        }
    
        public static class SayHello_call extends org.apache.thrift.async.TAsyncMethodCall<SayHelloResp> {
          private SayHelloReq req;
          public SayHello_call(SayHelloReq req, org.apache.thrift.async.AsyncMethodCallback<SayHelloResp> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
            super(client, protocolFactory, transport, resultHandler, false);
            this.req = req;
          }
    
          public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
            prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("SayHello", org.apache.thrift.protocol.TMessageType.CALL, 0));
            SayHello_args args = new SayHello_args();
            args.setReq(req);
            args.write(prot);
            prot.writeMessageEnd();
          }
    
          public SayHelloResp getResult() throws org.apache.thrift.TException {
            if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
              throw new java.lang.IllegalStateException("Method call not finished!");
            }
            org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
            org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
            return (new Client(prot)).recv_SayHello();
          }
        }
    
        public void SayBye(SayByeReq req, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
          checkReady();
          SayBye_call method_call = new SayBye_call(req, resultHandler, this, ___protocolFactory, ___transport);
          this.___currentMethod = method_call;
          ___manager.call(method_call);
        }
    
        public static class SayBye_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
          private SayByeReq req;
          public SayBye_call(SayByeReq req, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
            super(client, protocolFactory, transport, resultHandler, false);
            this.req = req;
          }
    
          public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
            prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("SayBye", org.apache.thrift.protocol.TMessageType.CALL, 0));
            SayBye_args args = new SayBye_args();
            args.setReq(req);
            args.write(prot);
            prot.writeMessageEnd();
          }
    
          public Void getResult() throws org.apache.thrift.TException {
            if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
              throw new java.lang.IllegalStateException("Method call not finished!");
            }
            org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
            org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
            return null;
          }
        }
    
      }
    
      public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
        private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName());
        public Processor(I iface) {
          super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
        }
    
        protected Processor(I iface, java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
          super(iface, getProcessMap(processMap));
        }
    
        private static <I extends Iface> java.util.Map<java.lang.String,  org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
          processMap.put("SayHello", new SayHello());
          processMap.put("SayBye", new SayBye());
          return processMap;
        }
    
        public static class SayHello<I extends Iface> extends org.apache.thrift.ProcessFunction<I, SayHello_args> {
          public SayHello() {
            super("SayHello");
          }
    
          public SayHello_args getEmptyArgsInstance() {
            return new SayHello_args();
          }
    
          protected boolean isOneway() {
            return false;
          }
    
          @Override
          protected boolean rethrowUnhandledExceptions() {
            return false;
          }
    
          public SayHello_result getResult(I iface, SayHello_args args) throws org.apache.thrift.TException {
            SayHello_result result = new SayHello_result();
            result.success = iface.SayHello(args.req);
            return result;
          }
        }
    
        public static class SayBye<I extends Iface> extends org.apache.thrift.ProcessFunction<I, SayBye_args> {
          public SayBye() {
            super("SayBye");
          }
    
          public SayBye_args getEmptyArgsInstance() {
            return new SayBye_args();
          }
    
          protected boolean isOneway() {
            return false;
          }
    
          @Override
          protected boolean rethrowUnhandledExceptions() {
            return false;
          }
    
          public SayBye_result getResult(I iface, SayBye_args args) throws org.apache.thrift.TException {
            SayBye_result result = new SayBye_result();
            iface.SayBye(args.req);
            return result;
          }
        }
    
      }
    
      public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
        private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());
        public AsyncProcessor(I iface) {
          super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
        }
    
        protected AsyncProcessor(I iface, java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
          super(iface, getProcessMap(processMap));
        }
    
        private static <I extends AsyncIface> java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
          processMap.put("SayHello", new SayHello());
          processMap.put("SayBye", new SayBye());
          return processMap;
        }
    
        public static class SayHello<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, SayHello_args, SayHelloResp> {
          public SayHello() {
            super("SayHello");
          }
    
          public SayHello_args getEmptyArgsInstance() {
            return new SayHello_args();
          }
    
          public org.apache.thrift.async.AsyncMethodCallback<SayHelloResp> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
            final org.apache.thrift.AsyncProcessFunction fcall = this;
            return new org.apache.thrift.async.AsyncMethodCallback<SayHelloResp>() { 
              public void onComplete(SayHelloResp o) {
                SayHello_result result = new SayHello_result();
                result.success = o;
                try {
                  fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
                } catch (org.apache.thrift.transport.TTransportException e) {
                  _LOGGER.error("TTransportException writing to internal frame buffer", e);
                  fb.close();
                } catch (java.lang.Exception e) {
                  _LOGGER.error("Exception writing to internal frame buffer", e);
                  onError(e);
                }
              }
              public void onError(java.lang.Exception e) {
                byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
                org.apache.thrift.TSerializable msg;
                SayHello_result result = new SayHello_result();
                if (e instanceof org.apache.thrift.transport.TTransportException) {
                  _LOGGER.error("TTransportException inside handler", e);
                  fb.close();
                  return;
                } else if (e instanceof org.apache.thrift.TApplicationException) {
                  _LOGGER.error("TApplicationException inside handler", e);
                  msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
                  msg = (org.apache.thrift.TApplicationException)e;
                } else {
                  _LOGGER.error("Exception inside handler", e);
                  msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
                  msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
                }
                try {
                  fcall.sendResponse(fb,msg,msgType,seqid);
                } catch (java.lang.Exception ex) {
                  _LOGGER.error("Exception writing to internal frame buffer", ex);
                  fb.close();
                }
              }
            };
          }
    
          protected boolean isOneway() {
            return false;
          }
    
          public void start(I iface, SayHello_args args, org.apache.thrift.async.AsyncMethodCallback<SayHelloResp> resultHandler) throws org.apache.thrift.TException {
            iface.SayHello(args.req,resultHandler);
          }
        }
    
        public static class SayBye<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, SayBye_args, Void> {
          public SayBye() {
            super("SayBye");
          }
    
          public SayBye_args getEmptyArgsInstance() {
            return new SayBye_args();
          }
    
          public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
            final org.apache.thrift.AsyncProcessFunction fcall = this;
            return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
              public void onComplete(Void o) {
                SayBye_result result = new SayBye_result();
                try {
                  fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
                } catch (org.apache.thrift.transport.TTransportException e) {
                  _LOGGER.error("TTransportException writing to internal frame buffer", e);
                  fb.close();
                } catch (java.lang.Exception e) {
                  _LOGGER.error("Exception writing to internal frame buffer", e);
                  onError(e);
                }
              }
              public void onError(java.lang.Exception e) {
                byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
                org.apache.thrift.TSerializable msg;
                SayBye_result result = new SayBye_result();
                if (e instanceof org.apache.thrift.transport.TTransportException) {
                  _LOGGER.error("TTransportException inside handler", e);
                  fb.close();
                  return;
                } else if (e instanceof org.apache.thrift.TApplicationException) {
                  _LOGGER.error("TApplicationException inside handler", e);
                  msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
                  msg = (org.apache.thrift.TApplicationException)e;
                } else {
                  _LOGGER.error("Exception inside handler", e);
                  msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
                  msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
                }
                try {
                  fcall.sendResponse(fb,msg,msgType,seqid);
                } catch (java.lang.Exception ex) {
                  _LOGGER.error("Exception writing to internal frame buffer", ex);
                  fb.close();
                }
              }
            };
          }
    
          protected boolean isOneway() {
            return false;
          }
    
          public void start(I iface, SayBye_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
            iface.SayBye(args.req,resultHandler);
          }
        }
    
      }
    
      public static class SayHello_args implements org.apache.thrift.TBase<SayHello_args, SayHello_args._Fields>, java.io.Serializable, Cloneable, Comparable<SayHello_args>   {
        private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SayHello_args");
    
        private static final org.apache.thrift.protocol.TField REQ_FIELD_DESC = new org.apache.thrift.protocol.TField("req", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    
        private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new SayHello_argsStandardSchemeFactory();
        private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new SayHello_argsTupleSchemeFactory();
    
        private @org.apache.thrift.annotation.Nullable SayHelloReq req; // required
    
        /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
        public enum _Fields implements org.apache.thrift.TFieldIdEnum {
          REQ((short)1, "req");
    
          private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
    
          static {
            for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
              byName.put(field.getFieldName(), field);
            }
          }
    
          /**
           * Find the _Fields constant that matches fieldId, or null if its not found.
           */
          @org.apache.thrift.annotation.Nullable
          public static _Fields findByThriftId(int fieldId) {
            switch(fieldId) {
              case 1: // REQ
                return REQ;
              default:
                return null;
            }
          }
    
          /**
           * Find the _Fields constant that matches fieldId, throwing an exception
           * if it is not found.
           */
          public static _Fields findByThriftIdOrThrow(int fieldId) {
            _Fields fields = findByThriftId(fieldId);
            if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
            return fields;
          }
    
          /**
           * Find the _Fields constant that matches name, or null if its not found.
           */
          @org.apache.thrift.annotation.Nullable
          public static _Fields findByName(java.lang.String name) {
            return byName.get(name);
          }
    
          private final short _thriftId;
          private final java.lang.String _fieldName;
    
          _Fields(short thriftId, java.lang.String fieldName) {
            _thriftId = thriftId;
            _fieldName = fieldName;
          }
    
          public short getThriftFieldId() {
            return _thriftId;
          }
    
          public java.lang.String getFieldName() {
            return _fieldName;
          }
        }
    
        // isset id assignments
        public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
        static {
          java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
          tmpMap.put(_Fields.REQ, new org.apache.thrift.meta_data.FieldMetaData("req", org.apache.thrift.TFieldRequirementType.DEFAULT, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SayHelloReq.class)));
          metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
          org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SayHello_args.class, metaDataMap);
        }
    
        public SayHello_args() {
        }
    
        public SayHello_args(
          SayHelloReq req)
        {
          this();
          this.req = req;
        }
    
        /**
         * Performs a deep copy on <i>other</i>.
         */
        public SayHello_args(SayHello_args other) {
          if (other.isSetReq()) {
            this.req = new SayHelloReq(other.req);
          }
        }
    
        public SayHello_args deepCopy() {
          return new SayHello_args(this);
        }
    
        @Override
        public void clear() {
          this.req = null;
        }
    
        @org.apache.thrift.annotation.Nullable
        public SayHelloReq getReq() {
          return this.req;
        }
    
        public void setReq(@org.apache.thrift.annotation.Nullable SayHelloReq req) {
          this.req = req;
        }
    
        public void unsetReq() {
          this.req = null;
        }
    
        /** Returns true if field req is set (has been assigned a value) and false otherwise */
        public boolean isSetReq() {
          return this.req != null;
        }
    
        public void setReqIsSet(boolean value) {
          if (!value) {
            this.req = null;
          }
        }
    
        public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
          switch (field) {
          case REQ:
            if (value == null) {
              unsetReq();
            } else {
              setReq((SayHelloReq)value);
            }
            break;
    
          }
        }
    
        @org.apache.thrift.annotation.Nullable
        public java.lang.Object getFieldValue(_Fields field) {
          switch (field) {
          case REQ:
            return getReq();
    
          }
          throw new java.lang.IllegalStateException();
        }
    
        /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
        public boolean isSet(_Fields field) {
          if (field == null) {
            throw new java.lang.IllegalArgumentException();
          }
    
          switch (field) {
          case REQ:
            return isSetReq();
          }
          throw new java.lang.IllegalStateException();
        }
    
        @Override
        public boolean equals(java.lang.Object that) {
          if (that == null)
            return false;
          if (that instanceof SayHello_args)
            return this.equals((SayHello_args)that);
          return false;
        }
    
        public boolean equals(SayHello_args that) {
          if (that == null)
            return false;
          if (this == that)
            return true;
    
          boolean this_present_req = true && this.isSetReq();
          boolean that_present_req = true && that.isSetReq();
          if (this_present_req || that_present_req) {
            if (!(this_present_req && that_present_req))
              return false;
            if (!this.req.equals(that.req))
              return false;
          }
    
          return true;
        }
    
        @Override
        public int hashCode() {
          int hashCode = 1;
    
          hashCode = hashCode * 8191 + ((isSetReq()) ? 131071 : 524287);
          if (isSetReq())
            hashCode = hashCode * 8191 + req.hashCode();
    
          return hashCode;
        }
    
        @Override
        public int compareTo(SayHello_args other) {
          if (!getClass().equals(other.getClass())) {
            return getClass().getName().compareTo(other.getClass().getName());
          }
    
          int lastComparison = 0;
    
          lastComparison = java.lang.Boolean.valueOf(isSetReq()).compareTo(other.isSetReq());
          if (lastComparison != 0) {
            return lastComparison;
          }
          if (isSetReq()) {
            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.req, other.req);
            if (lastComparison != 0) {
              return lastComparison;
            }
          }
          return 0;
        }
    
        @org.apache.thrift.annotation.Nullable
        public _Fields fieldForId(int fieldId) {
          return _Fields.findByThriftId(fieldId);
        }
    
        public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
          scheme(iprot).read(iprot, this);
        }
    
        public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
          scheme(oprot).write(oprot, this);
        }
    
        @Override
        public java.lang.String toString() {
          java.lang.StringBuilder sb = new java.lang.StringBuilder("SayHello_args(");
          boolean first = true;
    
          sb.append("req:");
          if (this.req == null) {
            sb.append("null");
          } else {
            sb.append(this.req);
          }
          first = false;
          sb.append(")");
          return sb.toString();
        }
    
        public void validate() throws org.apache.thrift.TException {
          // check for required fields
          // check for sub-struct validity
          if (req != null) {
            req.validate();
          }
        }
    
        private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
          try {
            write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
          } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
          }
        }
    
        private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
          try {
            read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
          } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
          }
        }
    
        private static class SayHello_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
          public SayHello_argsStandardScheme getScheme() {
            return new SayHello_argsStandardScheme();
          }
        }
    
        private static class SayHello_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<SayHello_args> {
    
          public void read(org.apache.thrift.protocol.TProtocol iprot, SayHello_args struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TField schemeField;
            iprot.readStructBegin();
            while (true)
            {
              schemeField = iprot.readFieldBegin();
              if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
                break;
              }
              switch (schemeField.id) {
                case 1: // REQ
                  if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                    struct.req = new SayHelloReq();
                    struct.req.read(iprot);
                    struct.setReqIsSet(true);
                  } else { 
                    org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
                  }
                  break;
                default:
                  org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              iprot.readFieldEnd();
            }
            iprot.readStructEnd();
            struct.validate();
          }
    
          public void write(org.apache.thrift.protocol.TProtocol oprot, SayHello_args struct) throws org.apache.thrift.TException {
            struct.validate();
    
            oprot.writeStructBegin(STRUCT_DESC);
            if (struct.req != null) {
              oprot.writeFieldBegin(REQ_FIELD_DESC);
              struct.req.write(oprot);
              oprot.writeFieldEnd();
            }
            oprot.writeFieldStop();
            oprot.writeStructEnd();
          }
    
        }
    
        private static class SayHello_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
          public SayHello_argsTupleScheme getScheme() {
            return new SayHello_argsTupleScheme();
          }
        }
    
        private static class SayHello_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<SayHello_args> {
    
          @Override
          public void write(org.apache.thrift.protocol.TProtocol prot, SayHello_args struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
            java.util.BitSet optionals = new java.util.BitSet();
            if (struct.isSetReq()) {
              optionals.set(0);
            }
            oprot.writeBitSet(optionals, 1);
            if (struct.isSetReq()) {
              struct.req.write(oprot);
            }
          }
    
          @Override
          public void read(org.apache.thrift.protocol.TProtocol prot, SayHello_args struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
            java.util.BitSet incoming = iprot.readBitSet(1);
            if (incoming.get(0)) {
              struct.req = new SayHelloReq();
              struct.req.read(iprot);
              struct.setReqIsSet(true);
            }
          }
        }
    
        private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
          return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
        }
      }
    
      public static class SayHello_result implements org.apache.thrift.TBase<SayHello_result, SayHello_result._Fields>, java.io.Serializable, Cloneable, Comparable<SayHello_result>   {
        private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SayHello_result");
    
        private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    
        private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new SayHello_resultStandardSchemeFactory();
        private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new SayHello_resultTupleSchemeFactory();
    
        private @org.apache.thrift.annotation.Nullable SayHelloResp success; // required
    
        /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
        public enum _Fields implements org.apache.thrift.TFieldIdEnum {
          SUCCESS((short)0, "success");
    
          private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
    
          static {
            for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
              byName.put(field.getFieldName(), field);
            }
          }
    
          /**
           * Find the _Fields constant that matches fieldId, or null if its not found.
           */
          @org.apache.thrift.annotation.Nullable
          public static _Fields findByThriftId(int fieldId) {
            switch(fieldId) {
              case 0: // SUCCESS
                return SUCCESS;
              default:
                return null;
            }
          }
    
          /**
           * Find the _Fields constant that matches fieldId, throwing an exception
           * if it is not found.
           */
          public static _Fields findByThriftIdOrThrow(int fieldId) {
            _Fields fields = findByThriftId(fieldId);
            if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
            return fields;
          }
    
          /**
           * Find the _Fields constant that matches name, or null if its not found.
           */
          @org.apache.thrift.annotation.Nullable
          public static _Fields findByName(java.lang.String name) {
            return byName.get(name);
          }
    
          private final short _thriftId;
          private final java.lang.String _fieldName;
    
          _Fields(short thriftId, java.lang.String fieldName) {
            _thriftId = thriftId;
            _fieldName = fieldName;
          }
    
          public short getThriftFieldId() {
            return _thriftId;
          }
    
          public java.lang.String getFieldName() {
            return _fieldName;
          }
        }
    
        // isset id assignments
        public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
        static {
          java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
          tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SayHelloResp.class)));
          metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
          org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SayHello_result.class, metaDataMap);
        }
    
        public SayHello_result() {
        }
    
        public SayHello_result(
          SayHelloResp success)
        {
          this();
          this.success = success;
        }
    
        /**
         * Performs a deep copy on <i>other</i>.
         */
        public SayHello_result(SayHello_result other) {
          if (other.isSetSuccess()) {
            this.success = new SayHelloResp(other.success);
          }
        }
    
        public SayHello_result deepCopy() {
          return new SayHello_result(this);
        }
    
        @Override
        public void clear() {
          this.success = null;
        }
    
        @org.apache.thrift.annotation.Nullable
        public SayHelloResp getSuccess() {
          return this.success;
        }
    
        public void setSuccess(@org.apache.thrift.annotation.Nullable SayHelloResp success) {
          this.success = success;
        }
    
        public void unsetSuccess() {
          this.success = null;
        }
    
        /** Returns true if field success is set (has been assigned a value) and false otherwise */
        public boolean isSetSuccess() {
          return this.success != null;
        }
    
        public void setSuccessIsSet(boolean value) {
          if (!value) {
            this.success = null;
          }
        }
    
        public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
          switch (field) {
          case SUCCESS:
            if (value == null) {
              unsetSuccess();
            } else {
              setSuccess((SayHelloResp)value);
            }
            break;
    
          }
        }
    
        @org.apache.thrift.annotation.Nullable
        public java.lang.Object getFieldValue(_Fields field) {
          switch (field) {
          case SUCCESS:
            return getSuccess();
    
          }
          throw new java.lang.IllegalStateException();
        }
    
        /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
        public boolean isSet(_Fields field) {
          if (field == null) {
            throw new java.lang.IllegalArgumentException();
          }
    
          switch (field) {
          case SUCCESS:
            return isSetSuccess();
          }
          throw new java.lang.IllegalStateException();
        }
    
        @Override
        public boolean equals(java.lang.Object that) {
          if (that == null)
            return false;
          if (that instanceof SayHello_result)
            return this.equals((SayHello_result)that);
          return false;
        }
    
        public boolean equals(SayHello_result that) {
          if (that == null)
            return false;
          if (this == that)
            return true;
    
          boolean this_present_success = true && this.isSetSuccess();
          boolean that_present_success = true && that.isSetSuccess();
          if (this_present_success || that_present_success) {
            if (!(this_present_success && that_present_success))
              return false;
            if (!this.success.equals(that.success))
              return false;
          }
    
          return true;
        }
    
        @Override
        public int hashCode() {
          int hashCode = 1;
    
          hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
          if (isSetSuccess())
            hashCode = hashCode * 8191 + success.hashCode();
    
          return hashCode;
        }
    
        @Override
        public int compareTo(SayHello_result other) {
          if (!getClass().equals(other.getClass())) {
            return getClass().getName().compareTo(other.getClass().getName());
          }
    
          int lastComparison = 0;
    
          lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
          if (lastComparison != 0) {
            return lastComparison;
          }
          if (isSetSuccess()) {
            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
            if (lastComparison != 0) {
              return lastComparison;
            }
          }
          return 0;
        }
    
        @org.apache.thrift.annotation.Nullable
        public _Fields fieldForId(int fieldId) {
          return _Fields.findByThriftId(fieldId);
        }
    
        public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
          scheme(iprot).read(iprot, this);
        }
    
        public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
          scheme(oprot).write(oprot, this);
          }
    
        @Override
        public java.lang.String toString() {
          java.lang.StringBuilder sb = new java.lang.StringBuilder("SayHello_result(");
          boolean first = true;
    
          sb.append("success:");
          if (this.success == null) {
            sb.append("null");
          } else {
            sb.append(this.success);
          }
          first = false;
          sb.append(")");
          return sb.toString();
        }
    
        public void validate() throws org.apache.thrift.TException {
          // check for required fields
          // check for sub-struct validity
          if (success != null) {
            success.validate();
          }
        }
    
        private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
          try {
            write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
          } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
          }
        }
    
        private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
          try {
            read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
          } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
          }
        }
    
        private static class SayHello_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
          public SayHello_resultStandardScheme getScheme() {
            return new SayHello_resultStandardScheme();
          }
        }
    
        private static class SayHello_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<SayHello_result> {
    
          public void read(org.apache.thrift.protocol.TProtocol iprot, SayHello_result struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TField schemeField;
            iprot.readStructBegin();
            while (true)
            {
              schemeField = iprot.readFieldBegin();
              if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
                break;
              }
              switch (schemeField.id) {
                case 0: // SUCCESS
                  if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                    struct.success = new SayHelloResp();
                    struct.success.read(iprot);
                    struct.setSuccessIsSet(true);
                  } else { 
                    org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
                  }
                  break;
                default:
                  org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              iprot.readFieldEnd();
            }
            iprot.readStructEnd();
            struct.validate();
          }
    
          public void write(org.apache.thrift.protocol.TProtocol oprot, SayHello_result struct) throws org.apache.thrift.TException {
            struct.validate();
    
            oprot.writeStructBegin(STRUCT_DESC);
            if (struct.success != null) {
              oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
              struct.success.write(oprot);
              oprot.writeFieldEnd();
            }
            oprot.writeFieldStop();
            oprot.writeStructEnd();
          }
    
        }
    
        private static class SayHello_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
          public SayHello_resultTupleScheme getScheme() {
            return new SayHello_resultTupleScheme();
          }
        }
    
        private static class SayHello_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<SayHello_result> {
    
          @Override
          public void write(org.apache.thrift.protocol.TProtocol prot, SayHello_result struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
            java.util.BitSet optionals = new java.util.BitSet();
            if (struct.isSetSuccess()) {
              optionals.set(0);
            }
            oprot.writeBitSet(optionals, 1);
            if (struct.isSetSuccess()) {
              struct.success.write(oprot);
            }
          }
    
          @Override
          public void read(org.apache.thrift.protocol.TProtocol prot, SayHello_result struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
            java.util.BitSet incoming = iprot.readBitSet(1);
            if (incoming.get(0)) {
              struct.success = new SayHelloResp();
              struct.success.read(iprot);
              struct.setSuccessIsSet(true);
            }
          }
        }
    
        private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
          return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
        }
      }
    
      public static class SayBye_args implements org.apache.thrift.TBase<SayBye_args, SayBye_args._Fields>, java.io.Serializable, Cloneable, Comparable<SayBye_args>   {
        private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SayBye_args");
    
        private static final org.apache.thrift.protocol.TField REQ_FIELD_DESC = new org.apache.thrift.protocol.TField("req", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    
        private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new SayBye_argsStandardSchemeFactory();
        private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new SayBye_argsTupleSchemeFactory();
    
        private @org.apache.thrift.annotation.Nullable SayByeReq req; // required
    
        /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
        public enum _Fields implements org.apache.thrift.TFieldIdEnum {
          REQ((short)1, "req");
    
          private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
    
          static {
            for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
              byName.put(field.getFieldName(), field);
            }
          }
    
          /**
           * Find the _Fields constant that matches fieldId, or null if its not found.
           */
          @org.apache.thrift.annotation.Nullable
          public static _Fields findByThriftId(int fieldId) {
            switch(fieldId) {
              case 1: // REQ
                return REQ;
              default:
                return null;
            }
          }
    
          /**
           * Find the _Fields constant that matches fieldId, throwing an exception
           * if it is not found.
           */
          public static _Fields findByThriftIdOrThrow(int fieldId) {
            _Fields fields = findByThriftId(fieldId);
            if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
            return fields;
          }
    
          /**
           * Find the _Fields constant that matches name, or null if its not found.
           */
          @org.apache.thrift.annotation.Nullable
          public static _Fields findByName(java.lang.String name) {
            return byName.get(name);
          }
    
          private final short _thriftId;
          private final java.lang.String _fieldName;
    
          _Fields(short thriftId, java.lang.String fieldName) {
            _thriftId = thriftId;
            _fieldName = fieldName;
          }
    
          public short getThriftFieldId() {
            return _thriftId;
          }
    
          public java.lang.String getFieldName() {
            return _fieldName;
          }
        }
    
        // isset id assignments
        public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
        static {
          java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
          tmpMap.put(_Fields.REQ, new org.apache.thrift.meta_data.FieldMetaData("req", org.apache.thrift.TFieldRequirementType.DEFAULT, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SayByeReq.class)));
          metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
          org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SayBye_args.class, metaDataMap);
        }
    
        public SayBye_args() {
        }
    
        public SayBye_args(
          SayByeReq req)
        {
          this();
          this.req = req;
        }
    
        /**
         * Performs a deep copy on <i>other</i>.
         */
        public SayBye_args(SayBye_args other) {
          if (other.isSetReq()) {
            this.req = new SayByeReq(other.req);
          }
        }
    
        public SayBye_args deepCopy() {
          return new SayBye_args(this);
        }
    
        @Override
        public void clear() {
          this.req = null;
        }
    
        @org.apache.thrift.annotation.Nullable
        public SayByeReq getReq() {
          return this.req;
        }
    
        public void setReq(@org.apache.thrift.annotation.Nullable SayByeReq req) {
          this.req = req;
        }
    
        public void unsetReq() {
          this.req = null;
        }
    
        /** Returns true if field req is set (has been assigned a value) and false otherwise */
        public boolean isSetReq() {
          return this.req != null;
        }
    
        public void setReqIsSet(boolean value) {
          if (!value) {
            this.req = null;
          }
        }
    
        public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
          switch (field) {
          case REQ:
            if (value == null) {
              unsetReq();
            } else {
              setReq((SayByeReq)value);
            }
            break;
    
          }
        }
    
        @org.apache.thrift.annotation.Nullable
        public java.lang.Object getFieldValue(_Fields field) {
          switch (field) {
          case REQ:
            return getReq();
    
          }
          throw new java.lang.IllegalStateException();
        }
    
        /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
        public boolean isSet(_Fields field) {
          if (field == null) {
            throw new java.lang.IllegalArgumentException();
          }
    
          switch (field) {
          case REQ:
            return isSetReq();
          }
          throw new java.lang.IllegalStateException();
        }
    
        @Override
        public boolean equals(java.lang.Object that) {
          if (that == null)
            return false;
          if (that instanceof SayBye_args)
            return this.equals((SayBye_args)that);
          return false;
        }
    
        public boolean equals(SayBye_args that) {
          if (that == null)
            return false;
          if (this == that)
            return true;
    
          boolean this_present_req = true && this.isSetReq();
          boolean that_present_req = true && that.isSetReq();
          if (this_present_req || that_present_req) {
            if (!(this_present_req && that_present_req))
              return false;
            if (!this.req.equals(that.req))
              return false;
          }
    
          return true;
        }
    
        @Override
        public int hashCode() {
          int hashCode = 1;
    
          hashCode = hashCode * 8191 + ((isSetReq()) ? 131071 : 524287);
          if (isSetReq())
            hashCode = hashCode * 8191 + req.hashCode();
    
          return hashCode;
        }
    
        @Override
        public int compareTo(SayBye_args other) {
          if (!getClass().equals(other.getClass())) {
            return getClass().getName().compareTo(other.getClass().getName());
          }
    
          int lastComparison = 0;
    
          lastComparison = java.lang.Boolean.valueOf(isSetReq()).compareTo(other.isSetReq());
          if (lastComparison != 0) {
            return lastComparison;
          }
          if (isSetReq()) {
            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.req, other.req);
            if (lastComparison != 0) {
              return lastComparison;
            }
          }
          return 0;
        }
    
        @org.apache.thrift.annotation.Nullable
        public _Fields fieldForId(int fieldId) {
          return _Fields.findByThriftId(fieldId);
        }
    
        public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
          scheme(iprot).read(iprot, this);
        }
    
        public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
          scheme(oprot).write(oprot, this);
        }
    
        @Override
        public java.lang.String toString() {
          java.lang.StringBuilder sb = new java.lang.StringBuilder("SayBye_args(");
          boolean first = true;
    
          sb.append("req:");
          if (this.req == null) {
            sb.append("null");
          } else {
            sb.append(this.req);
          }
          first = false;
          sb.append(")");
          return sb.toString();
        }
    
        public void validate() throws org.apache.thrift.TException {
          // check for required fields
          // check for sub-struct validity
          if (req != null) {
            req.validate();
          }
        }
    
        private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
          try {
            write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
          } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
          }
        }
    
        private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
          try {
            read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
          } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
          }
        }
    
        private static class SayBye_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
          public SayBye_argsStandardScheme getScheme() {
            return new SayBye_argsStandardScheme();
          }
        }
    
        private static class SayBye_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<SayBye_args> {
    
          public void read(org.apache.thrift.protocol.TProtocol iprot, SayBye_args struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TField schemeField;
            iprot.readStructBegin();
            while (true)
            {
              schemeField = iprot.readFieldBegin();
              if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
                break;
              }
              switch (schemeField.id) {
                case 1: // REQ
                  if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                    struct.req = new SayByeReq();
                    struct.req.read(iprot);
                    struct.setReqIsSet(true);
                  } else { 
                    org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
                  }
                  break;
                default:
                  org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              iprot.readFieldEnd();
            }
            iprot.readStructEnd();
            struct.validate();
          }
    
          public void write(org.apache.thrift.protocol.TProtocol oprot, SayBye_args struct) throws org.apache.thrift.TException {
            struct.validate();
    
            oprot.writeStructBegin(STRUCT_DESC);
            if (struct.req != null) {
              oprot.writeFieldBegin(REQ_FIELD_DESC);
              struct.req.write(oprot);
              oprot.writeFieldEnd();
            }
            oprot.writeFieldStop();
            oprot.writeStructEnd();
          }
    
        }
    
        private static class SayBye_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
          public SayBye_argsTupleScheme getScheme() {
            return new SayBye_argsTupleScheme();
          }
        }
    
        private static class SayBye_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<SayBye_args> {
    
          @Override
          public void write(org.apache.thrift.protocol.TProtocol prot, SayBye_args struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
            java.util.BitSet optionals = new java.util.BitSet();
            if (struct.isSetReq()) {
              optionals.set(0);
            }
            oprot.writeBitSet(optionals, 1);
            if (struct.isSetReq()) {
              struct.req.write(oprot);
            }
          }
    
          @Override
          public void read(org.apache.thrift.protocol.TProtocol prot, SayBye_args struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
            java.util.BitSet incoming = iprot.readBitSet(1);
            if (incoming.get(0)) {
              struct.req = new SayByeReq();
              struct.req.read(iprot);
              struct.setReqIsSet(true);
            }
          }
        }
    
        private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
          return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
        }
      }
    
      public static class SayBye_result implements org.apache.thrift.TBase<SayBye_result, SayBye_result._Fields>, java.io.Serializable, Cloneable, Comparable<SayBye_result>   {
        private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SayBye_result");
    
    
        private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new SayBye_resultStandardSchemeFactory();
        private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new SayBye_resultTupleSchemeFactory();
    
    
        /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
        public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    ;
    
          private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
    
          static {
            for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
              byName.put(field.getFieldName(), field);
            }
          }
    
          /**
           * Find the _Fields constant that matches fieldId, or null if its not found.
           */
          @org.apache.thrift.annotation.Nullable
          public static _Fields findByThriftId(int fieldId) {
            switch(fieldId) {
              default:
                return null;
            }
          }
    
          /**
           * Find the _Fields constant that matches fieldId, throwing an exception
           * if it is not found.
           */
          public static _Fields findByThriftIdOrThrow(int fieldId) {
            _Fields fields = findByThriftId(fieldId);
            if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
            return fields;
          }
    
          /**
           * Find the _Fields constant that matches name, or null if its not found.
           */
          @org.apache.thrift.annotation.Nullable
          public static _Fields findByName(java.lang.String name) {
            return byName.get(name);
          }
    
          private final short _thriftId;
          private final java.lang.String _fieldName;
    
          _Fields(short thriftId, java.lang.String fieldName) {
            _thriftId = thriftId;
            _fieldName = fieldName;
          }
    
          public short getThriftFieldId() {
            return _thriftId;
          }
    
          public java.lang.String getFieldName() {
            return _fieldName;
          }
        }
        public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
        static {
          java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
          metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
          org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SayBye_result.class, metaDataMap);
        }
    
        public SayBye_result() {
        }
    
        /**
         * Performs a deep copy on <i>other</i>.
         */
        public SayBye_result(SayBye_result other) {
        }
    
        public SayBye_result deepCopy() {
          return new SayBye_result(this);
        }
    
        @Override
        public void clear() {
        }
    
        public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
          switch (field) {
          }
        }
    
        @org.apache.thrift.annotation.Nullable
        public java.lang.Object getFieldValue(_Fields field) {
          switch (field) {
          }
          throw new java.lang.IllegalStateException();
        }
    
        /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
        public boolean isSet(_Fields field) {
          if (field == null) {
            throw new java.lang.IllegalArgumentException();
          }
    
          switch (field) {
          }
          throw new java.lang.IllegalStateException();
        }
    
        @Override
        public boolean equals(java.lang.Object that) {
          if (that == null)
            return false;
          if (that instanceof SayBye_result)
            return this.equals((SayBye_result)that);
          return false;
        }
    
        public boolean equals(SayBye_result that) {
          if (that == null)
            return false;
          if (this == that)
            return true;
    
          return true;
        }
    
        @Override
        public int hashCode() {
          int hashCode = 1;
    
          return hashCode;
        }
    
        @Override
        public int compareTo(SayBye_result other) {
          if (!getClass().equals(other.getClass())) {
            return getClass().getName().compareTo(other.getClass().getName());
          }
    
          int lastComparison = 0;
    
          return 0;
        }
    
        @org.apache.thrift.annotation.Nullable
        public _Fields fieldForId(int fieldId) {
          return _Fields.findByThriftId(fieldId);
        }
    
        public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
          scheme(iprot).read(iprot, this);
        }
    
        public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
          scheme(oprot).write(oprot, this);
          }
    
        @Override
        public java.lang.String toString() {
          java.lang.StringBuilder sb = new java.lang.StringBuilder("SayBye_result(");
          boolean first = true;
    
          sb.append(")");
          return sb.toString();
        }
    
        public void validate() throws org.apache.thrift.TException {
          // check for required fields
          // check for sub-struct validity
        }
    
        private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
          try {
            write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
          } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
          }
        }
    
        private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
          try {
            read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
          } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
          }
        }
    
        private static class SayBye_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
          public SayBye_resultStandardScheme getScheme() {
            return new SayBye_resultStandardScheme();
          }
        }
    
        private static class SayBye_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<SayBye_result> {
    
          public void read(org.apache.thrift.protocol.TProtocol iprot, SayBye_result struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TField schemeField;
            iprot.readStructBegin();
            while (true)
            {
              schemeField = iprot.readFieldBegin();
              if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
                break;
              }
              switch (schemeField.id) {
                default:
                  org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              iprot.readFieldEnd();
            }
            iprot.readStructEnd();
            struct.validate();
          }
    
          public void write(org.apache.thrift.protocol.TProtocol oprot, SayBye_result struct) throws org.apache.thrift.TException {
            struct.validate();
    
            oprot.writeStructBegin(STRUCT_DESC);
            oprot.writeFieldStop();
            oprot.writeStructEnd();
          }
    
        }
    
        private static class SayBye_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
          public SayBye_resultTupleScheme getScheme() {
            return new SayBye_resultTupleScheme();
          }
        }
    
        private static class SayBye_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<SayBye_result> {
    
          @Override
          public void write(org.apache.thrift.protocol.TProtocol prot, SayBye_result struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
          }
    
          @Override
          public void read(org.apache.thrift.protocol.TProtocol prot, SayBye_result struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
          }
        }
    
        private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
          return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
        }
      }
    
    }
    

    </code></pre>
    </details>

    相关文章

      网友评论

          本文标题:Thrift架构及源码解读

          本文链接:https://www.haomeiwen.com/subject/fsypnctx.html