[
https://issues.apache.org/jira/browse/THRIFT-171?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12640670#action_12640670
]
Dave Dupre commented on THRIFT-171:
-----------------------------------
I've been playing with this for a bit, and I can make it happen now in an all
Ruby env. I attempted to use a more threaded server and followed the same basic
pattern that Mongrel uses in its processing loop. Everything works fine until
you get a couple of clients hitting the server at the same time. When that
happens, I get:
/Library/Ruby/Site/1.8/thrift/transport/socket.rb:94:in `read': end of file
reached (Thrift::TransportException)
from /Library/Ruby/Site/1.8/thrift/transport.rb:103:in `read'
from /Library/Ruby/Site/1.8/thrift/transport.rb:44:in `read_all'
from /Library/Ruby/Site/1.8/thrift/protocol/binaryprotocol.rb:143:in
`read_i32'
from /Library/Ruby/Site/1.8/thrift/protocol/binaryprotocol.rb:80:in
`read_message_begin'
from /Library/Ruby/Site/1.8/thrift/client.rb:26:in `receive_message'
from ./script/../lib/gen-rb/JobsService.rb:26:in `recv_search'
from ./script/../lib/gen-rb/JobsService.rb:18:in `search'
from script/jobs_client:22
from script/jobs_client:17:in `times'
from script/jobs_client:17
Then, I cooked up the example that is attached to this ticket. I see two
different behaviors based on where the transport.open/close calls are. When
the calls are inside the loop, all clients will hang once I start up 6-7 of
them. Once hung, none will ever move again (even new ones). If I close all
clients, then new clients execute normally again.
When the calls are outside the loop and the server is a SimpleServer, each new
client will block until the previous client completes. Use the ThreadedServer,
and things run fine. However, I don't think leaving the transport open will
work in my environment.
Everything is done using the latest version of Thrift downloaded from the
Apache site.
Here is my serve method from the Server class that I built for my purposes. I
removed a lot of the cleanup and error handling so you can see the meat of it.
# Listen on the port and process requests. This is very similar to the
mongrel listen loop.
# It returns the thread used so you can "join" it. You can also access the
Server::acceptor
# attribute to get the thread later. We do things this way so that we can
have the main
# thread watch and stop our listener gracefully.
def serve()
@acceptor = Thread.new do
begin
@server_transport.listen()
loop do
begin
client = @server_transport.accept()
transport = @transport_factory.get_transport(client)
protocol = @protocol_factory.get_protocol(transport)
thread = Thread.new(client, transport, protocol) do |c, t, p|
begin
handler = @handler_class.new()
processor = @processor_class.new(handler)
loop do
processor.process(p, p)
end
rescue Thrift::TransportException, Thrift::ProtocolException
ensure
t.close()
end
end
thread[:started_on] = Time.now
@workers.add(thread)
end
end
end
ensure
@server_transport.close()
end
end
return @acceptor
end
With this method I get the errors from the client above as soon as I fire up a
second client. The server remains healthy.
I notice that the new Thrift includes a Mongrel handler. I will investigate
that now, but I would prefer to keep things as simple as possible.
Thanks in advance.
-Dave
> Expected blocking from TSocket but didn't get it
> ------------------------------------------------
>
> Key: THRIFT-171
> URL: https://issues.apache.org/jira/browse/THRIFT-171
> Project: Thrift
> Issue Type: Bug
> Components: Library (Java), Library (Ruby)
> Affects Versions: 0.1
> Environment: CentOS 4.x
> Reporter: Dave Dupre
> Attachments: try.zip
>
>
> I have a Thrift server built in Ruby on Rails. It uses the TSimpleServer
> class since my server is using Rails to generate HTML (Rails view code
> expects to be single threaded). I have two clients: one in Java and one in
> Ruby. Here is what I see:
> Ruby client:
> # Usual init code straight from the tutorial here
> transport.open
> 1000.times { client.my_method }
> transport.close
> The Java client is basically the same. Unfortunately, I see two different
> behaviors when running multiple client instances. With a Ruby client,
> execute client A, and it starts processing normally. Execute client B while
> client A is still running, and it blocks at transport.open until client A
> completes. This is what I expected. However, if I do the same thing with
> Java clients, both clients proceed in parallel. Unfortunately, this gets the
> server very confused and into a really bad state. I'm using TSocket which
> should be doing blocking I/O, but that is not what I'm seeing happen.
> Is there some magic that I can do to make this work? Right now, I use
> configuration to ensure that only one Java client thread/process is allowed
> to talk to my Ruby server, but this is a total hack. Switching to
> TThreadedServer makes blocking go away, but I'm nervous about what that will
> mean to the Rails controller and view code. FYI, my server allows me to
> generate HTML views via Thrift. If it was a pure Ruby server, then I would
> not be concerned, but since so much is dependent on code that usually assumes
> to be single threaded, I'm concerned about introducing bugs.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.