3

I am running a pair of client and server programs communicating using Apache Thrift on my Mac. In our production system we may end up in a situation where the client uses TJSONProtocol and the server uses TBinaryProtocol for serialization and deserialization.

I know that this is a terrible thing. But I am not sure how to detect this before hand. I tried a sample program with different protocols. I was expecting to receive an exception, but the client got stuck on the RPC call and never returned.

Server code using TBinaryProtocol:

shared_ptr<SomethingHandler> handler(new SomethingHandler());
shared_ptr<TProcessor> processor(new SomethingProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();

Client code using TJSONProtocol:

boost::shared_ptr < TSocket > socket(new TSocket(argv[1], 9090));
boost::shared_ptr < TTransport > transport(new TBufferedTransport(socket));
boost::shared_ptr < TProtocol > protocol(new TJSONProtocol(transport));
transport->open();
std::cout<<"Transport open success"<<std::endl;
SomethingClient client(protocol);
std::cout<<"Create client success"<<std::endl;
try{
    std::cout<<"About to ping"<<std::endl;
    client.ping(argv[2]);
    std::cout<<"Ping success"<<std::endl;
    }catch(TException e){
    std::cout<<"Exception occurred:"<<e.what()<<std::endl;
}
transport->close();

In this example, I never get Ping success to print. Is there any way I can detect this incompatibility without getting stuck?

CCoder
  • 2,305
  • 19
  • 41

1 Answers1

4

I'm afraid you can't. By definition, you are expected to set up the exact same protocol/transport stack 1) on both ends; anything else is just plain invalid.

If you need different protocol/transport stacks, you need to set up the appropriate number of different endpoints.

There is no protection or detection other than the usual mechanisms on higher levels of the stack. The reason why you got stuck is very likely a misinterpretation of the data, so the server probably just waits for more request bytes to come in, which you don't send.


1) There are some exceptions to that rule, but they do not matter here.

Wandering Fool
  • 2,170
  • 3
  • 18
  • 48
JensG
  • 13,148
  • 4
  • 45
  • 55
  • 1
    Oh that's too bad. I wanted to control which protocol I use dynamically while running the programs so that I can switch to JSON/debug protocol for debugging and Binary for production run. I am worried in some cases during testing, we may end up in a situation where the config is mismatched leading to mismatched protocol. – CCoder Aug 08 '15 at 06:37
  • 1
    What about also using different ports for debug/release? – JensG Aug 08 '15 at 10:05
  • If it's for debug purpose only it can be just program option (or even compilation option) - you should rarely need to use debug, and when needed just setup debug environment with differently started client&server. – Hcorg Aug 25 '15 at 11:12