Thrift架构及源码解读

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依赖


  org.apache.thrift
  libthrift
  0.13.0

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

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

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

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

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

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

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

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

public static class SayHello extends org.apache.thrift.ProcessFunction
参数类:命名规则: 函数名 + “_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(),
          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 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 resultHandler) throws org.apache.thrift.TException;

    public void SayBye(SayByeReq req, org.apache.thrift.async.AsyncMethodCallback 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 {
      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 {
      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 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 {
      private SayHelloReq req;
      public SayHello_call(SayHelloReq req, org.apache.thrift.async.AsyncMethodCallback 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 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 {
      private SayByeReq req;
      public SayBye_call(SayByeReq req, org.apache.thrift.async.AsyncMethodCallback 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 extends org.apache.thrift.TBaseProcessor 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>()));
    }

    protected Processor(I iface, java.util.Map> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static  java.util.Map> getProcessMap(java.util.Map> processMap) {
      processMap.put("SayHello", new SayHello());
      processMap.put("SayBye", new SayBye());
      return processMap;
    }

    public static class SayHello extends org.apache.thrift.ProcessFunction {
      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 extends org.apache.thrift.ProcessFunction {
      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 extends org.apache.thrift.TBaseAsyncProcessor {
    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>()));
    }

    protected AsyncProcessor(I iface, java.util.Map> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static  java.util.Map> getProcessMap(java.util.Map> processMap) {
      processMap.put("SayHello", new SayHello());
      processMap.put("SayBye", new SayBye());
      return processMap;
    }

    public static class SayHello extends org.apache.thrift.AsyncProcessFunction {
      public SayHello() {
        super("SayHello");
      }

      public SayHello_args getEmptyArgsInstance() {
        return new SayHello_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback 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() { 
          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 resultHandler) throws org.apache.thrift.TException {
        iface.SayHello(args.req,resultHandler);
      }
    }

    public static class SayBye extends org.apache.thrift.AsyncProcessFunction {
      public SayBye() {
        super("SayBye");
      }

      public SayBye_args getEmptyArgsInstance() {
        return new SayBye_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback 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() { 
          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 resultHandler) throws org.apache.thrift.TException {
        iface.SayBye(args.req,resultHandler);
      }
    }

  }

  public static class SayHello_args implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable   {
    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 byName = new java.util.HashMap();

      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 other.
     */
    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 {

      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 {

      @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 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, java.io.Serializable, Cloneable, Comparable   {
    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 byName = new java.util.HashMap();

      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 other.
     */
    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 {

      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 {

      @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 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, java.io.Serializable, Cloneable, Comparable   {
    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 byName = new java.util.HashMap();

      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 other.
     */
    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 {

      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 {

      @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 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, java.io.Serializable, Cloneable, Comparable   {
    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 byName = new java.util.HashMap();

      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 other.
     */
    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 {

      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 {

      @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 scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

}


你可能感兴趣的:(Thrift架构及源码解读)