[
https://issues.apache.org/jira/browse/THRIFT-4858?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Aki Sukegawa resolved THRIFT-4858.
----------------------------------
Assignee: Aki Sukegawa
Resolution: Fixed
Please reopen if this persists with current master or anywhere after
[https://github.com/apache/thrift/commit/c35ed736d26a1dfd8965ae197a67904ed9b4fba3#diff-c6a81da7e9ec5ce3c040a3386a790b69R321]
> Java TThreadPoolServer calls TBaseProcesser twice, erroneously
> --------------------------------------------------------------
>
> Key: THRIFT-4858
> URL: https://issues.apache.org/jira/browse/THRIFT-4858
> Project: Thrift
> Issue Type: Bug
> Components: Java - Library
> Affects Versions: 0.12.0
> Environment: Here is some information on my environment and code that
> calls Thrift.
> Environment: Red Hat Linux 7.6, Java 1.8, Thrift 0.12.0. Both my client and
> server are in Java. However, I have also seen this when a Python client calls
> the Java server.
> Here is what I do to set up the server, my service Iface name is
> "AlgorithmRepository" ...
> {{TServerTransport transport = new TServerSocket(10202);}}
> {{ TProcessor processor = new AlgorithmRepository.Processor<>(this);}}
> {{ Args args = new
> TThreadPoolServer.Args(transport).processor(processor).inputTransportFactory(new
> TFramedTransport.Factory()).outputTransportFactory(new
> TFramedTransport.Factory()).protocolFactory(new TBinaryProtocol.Factory());}}
> {{ final TServer server = new TThreadPoolServer(args);}}
> {{ new Thread(server::serve).start();}}
> That last line corresponds to the Thread you see at the bottom of the
> exception.
> It is worth noting we did also set the Input and Output Protocol Factories
> too and it had no affect on the result.
> We saw on stackoverflow that if you don't have the same Transport type, it
> will fail to function. Here is client code that sets this up:
> {{TTransport transport = new TFramedTransport(new TSocket(host, port,
> socketTimeoutMillis));}}
> I'd be happy to share more client code if you felt it was something the
> client is doing wrong.
>
> Reporter: Michael Czajkowski
> Assignee: Aki Sukegawa
> Priority: Major
> Fix For: 0.13.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> I've spotted an error in using java libthrift that I'd like to call to your
> attention. It is in version 0.12.0, but I see it in other versions. I will
> comment about the other versions at the end, please read - it may be very
> *important* to you.
> I create a TThreadPoolServer, and when my client calls a method, the server
> spawns off a worker thread and when it gets to this line (in
> TThreadPoolServer):
> {{if(stopped_ || !processor.process(inputProtocol, outputProtocol)) {}}
> {{break;}}
> }
> It will call a TBaseProcessor's process method, which can only return either
> True or throw an Exception. In my case, it gets to the very bottom and calls
> the ProcessFunction fn properly:
> {{fn.process(msg.seqid, in, out, iface);}}
> Followed by returning true. However, since the TThreadPoolServer will not
> "break" out of the while(true) loop it is in, it will attempt to call the
> TBaseProcessor's process method again and this time around I get an exception
> when this line is called on TBaseProcessor's process method:
> {{TMessage msg = in.readMessageBegin();}}
> Exception is:
> 17844 [pool-6-thread-5] ERROR org.apache.thrift.server.TThreadPoolServer -
> Thrift error occurred during processing of message.
> {{org.apache.thrift.transport.TTransportException}}
> at
> org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:132
> at org.apache.thrift.transport.TTransport.readAll(TTransport.java:86)
> at
> org.apache.thrift.transport.TFramedTransport.readFrame(TFramedTransport.java:132)
> at
> org.apache.thrift.transport.TFramedTransport.read(TFramedTransport.java:100)
> at org.apache.thrift.transport.TTransport.readAll(TTransport.java:86)
> at
> org.apache.thrift.protocol.TBinaryProtocol.readAll(TBinaryProtocol.java:425)
> at
> org.apache.thrift.protocol.TBinaryProtocol.readI32(TBinaryProtocol.java:321)
> at
> org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin(TBinaryProtocol.java:225)
> at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:33)
> at
> org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:318)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
> at java.lang.Thread.run(Thread.java:748)
> I surmise because my TProtocol in has already sent the bytes (I am using a
> TBinaryProtocol) to the process function, there is nothing left to read and
> thus we never make it to the next line:
> {{ProcessFunction fn = processMap.get(msg.name);}}
> For giggles, I decided to remove the ! from the logic, and sure enough it
> gets by but it appears to perhaps cause other problems when a client calls a
> method with zero parameters (e.g. "ping()").
> *Other versions:* So far as I can tell this exact same code set up is in java
> libthrift 0.9.0, 0.9.1, and 0.9.3.1. However, my Java code works just fine in
> those. I only discovered this problem when I went to upgrade my code to
> Thrift 0.12.0. I honestly can't make sense of why that would be OK in those
> older versions but, I've been blissfully unaware of this problem until the
> upgrade. It is possible I need to now do something that I did not before.
> That is because before, I used TThreadPoolServer with 0.9.x as I want to do
> now in 0.12.x. I figured perhaps something else is happening in Thrift with
> my TThreadPoolServer. Finally, I did see the problem in 0.12.1 and did not
> test it, though it appears changed in the master branch - we tried it and it
> still has errors.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)