thrift-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rush Manbert <r...@manbert.com>
Subject Re: reuse Ttransport or not ?
Date Fri, 20 Jul 2012 15:58:31 GMT
Disclaimer: I know a lot about the C++ implementation, but I'm not a Java guy and have never
looked at the Java code.

That being said:
As near as I can tell, the code as written should work, and you should be able to call updateMemCache()
any number of times using the single client object.

The fact that you get 3 successful calls suggests that there is some sort of race and some
code thread completed and closed the transport when you didn't expect it. There's something
in the stack trace called java.util.concurrent.ThreadPoolExecutor$Worker.runTask that makes
me doubly suspicious, but, as I said, I don't write Java code, so I don't know what the real
implications might be.

If I were debugging this I would put a breakpoint in transport.close() and I would also monitor
what's happening on the server side to see if it closes the socket for some reason.

Do any of you Jave guys have anything to add? Maybe Bryan?

- Rush

On Jul 19, 2012, at 9:26 PM, panfei wrote:

> Hi Rush:
> 
> very thank you for your kindly help. but I encountered a  strange problem,
> I use only one TSocket object to connect to a thrift server and then do rpc
> calls in a for loop (10 calls), but it gives:
> 
> *TTransport transport = null;*
> * *
> * try{*
> * transport = new TSocket(host, port); *
> * TProtocol protocol = new TBinaryProtocol(transport); *
> * BIClientServer.Client client = new BIClientServer.Client(protocol);*
> * transport.open(); *
> * *
> * for(String arg : args){*
> * logger.info(String.format("[%s] need value for key [%s]", hostport, arg));
> *
> * String val = hb.get(arg);*
> * client.updateMemCache(arg, val); *
> * }*
> * }catch(Exception e){*
> * e.printStackTrace();*
> * }finally{*
> * transport.close(); *
> * }*
> 
> it report exception as follows, only 3 of 10 calls succeeds, I want to know
> how to solve it , I really want to reuse TSocket... thanks:
> 
> org.apache.thrift.transport.TTransportException: java.net.SocketException:
> Broken pipe
>        at
> org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:161)
>        at
> com.hoolai.dataservice.BIClientServer$Client.send_updateMemCache(BIClientServer.java:105)
>        at
> com.hoolai.dataservice.BIClientServer$Client.updateMemCache(BIClientServer.java:94)
>        at
> com.hoolai.dataservice.BIServerHandler.processUpdateMemCacheSignalAgent(BIServerHandler.java:111)
>        at
> com.hoolai.dataservice.utils.ServerConsumer.run(ServerConsumer.java:38)
>        at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>        at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>        at java.lang.Thread.run(Thread.java:662)
> Caused by: java.net.SocketException: Broken pipe
>        at java.net.SocketOutputStream.socketWrite0(Native Method)
>        at
> java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
>        at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
>        at
> java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
>        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
>        at
> org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:159)
> 
> 
> after I change the code as follow , it works well -_- :
> 
> try{
> for(String arg : args){
> transport = new TSocket(host, port); // 底层数据传输层
> TProtocol protocol = new TBinaryProtocol(transport); // 对数据读写的封装协议
> BIClientServer.Client client = new BIClientServer.Client(protocol);
> transport.open(); // 连接到远程Server
> System.out.println("********");
> logger.info(String.format("[%s] need value for key [%s]", hostport, arg));
> String val = hb.get(arg);
> client.updateMemCache(arg, val); // arg就是key
> }
> }catch(Exception e){
> e.printStackTrace();
> }finally{
> transport.close(); // 处理完之后关闭transport
> }
> 
> 2012/7/20 Rush Manbert <rush@manbert.com>
> 
>> On Jul 18, 2012, at 11:45 PM, panfei wrote:
>> 
>>> Hi all:
>>> 
>>> there maybe a lot of RPC calls from the client to the server, I want to
>>> know , in this case, should I create a transport and keep it opened to do
>>> the RPC calls , or should I create a transport on every RPC call ? and
>> why
>>> ? thanks !
>>> 
>>> 
>>> --
>>> 不学习,不知道
>> 
>> On a *nix system, opening a transport for each RPC call uses a socket.
>> When you close the transport, the system keeps the socket around for a
>> while, so it is unavailable for re-use. Depending on the rate at which you
>> make RPC calls, your system can get starved for sockets, and you will need
>> to add retry logic to handle that. So it's better to open a single client
>> and use it for multiple calls.
>> 
>> I'm guessing you would see the same effect from a Windows client.
>> 
>> - Rush
> 
> 
> 
> 
> -- 
> 不学习,不知道


Mime
View raw message