[ https://issues.apache.org/jira/browse/THRIFT-4858?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16923486#comment-16923486 ]
Oleksiy Sayankin edited comment on THRIFT-4858 at 9/5/19 2:33 PM: ------------------------------------------------------------------ Absolutely the same happens when user closes connection to HiveServer2. See class {{TThreadPoolServer}} method {{run()}} {code:java} while (true) { if (eventHandler != null) { eventHandler.processContext(connectionContext, inputTransport, outputTransport); } if(stopped_ || !processor.process(inputProtocol, outputProtocol)) { break; } } } catch (TException tx) { LOGGER.error("Thrift error occurred during processing of message.", tx); {code} JVM executes {code:java} processor.process(inputProtocol, outputProtocol) {code} during the connection closure, and {{processor.process(...)}} returns {{true}} since connection was successfully closed. Then it goes to the next iteration of {{while(true)}} loop and tries to process it again but can't read bytes and throws {{TTransportException}} at {{org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:132)}}. was (Author: osayankin): Absolutely the same happens when user closes connection to HS2. See class {{TThreadPoolServer}} method {{run()}} {code} while (true) { if (eventHandler != null) { eventHandler.processContext(connectionContext, inputTransport, outputTransport); } if(stopped_ || !processor.process(inputProtocol, outputProtocol)) { break; } } } catch (TException tx) { LOGGER.error("Thrift error occurred during processing of message.", tx); {code} JVM executes {code} processor.process(inputProtocol, outputProtocol) {code} during the connection closure, and {{processor.process(...)}} returns {{true}} since connection was successfully closed. Then it goes to the next iteration of {{while(true)}} loop and tries to process it again but can't read bytes and throws {{TTransportException}} at {{org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:132)}}. > 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 > Priority: Major > > 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.2#803003)