add additional entrypoint to TThreadPoolServer with easy exception handling
An additional method #serve_rescuable is added, which relays any exceptions
that happen in worker threads to the caller, where they can be handled
directly. 'retry' works too, allowing code like:
begin
server.rescuable_serve
rescue StandardError => e
puts "got exception: #{e.inspect}"
## do something
retry
end
The semantics of TThreadPoolServer#serve remain the same.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@668891 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/rb/lib/thrift/server/tserver.rb b/lib/rb/lib/thrift/server/tserver.rb
index 43b2bdd..f2239c8 100644
--- a/lib/rb/lib/thrift/server/tserver.rb
+++ b/lib/rb/lib/thrift/server/tserver.rb
@@ -88,15 +88,27 @@
class TThreadPoolServer < TServer
def initialize(processor, serverTransport, transportFactory=nil, protocolFactory=nil, num=20)
super(processor, serverTransport, transportFactory, protocolFactory)
- @q = SizedQueue.new(num)
+ @thread_q = SizedQueue.new(num)
+ @exception_q = Queue.new
+ @running = false
end
- def serve()
+ ## exceptions that happen in worker threads will be relayed here and
+ ## must be caught. 'retry' can be used to continue. (threads will
+ ## continue to run while the exception is being handled.)
+ def rescuable_serve
+ Thread.new { serve } unless @running
+ raise @exception_q.pop
+ end
+
+ ## exceptions that happen in worker threads simply cause that thread
+ ## to die and another to be spawned in its place.
+ def serve
@serverTransport.listen()
begin
while (true)
- @q.push(:token)
+ @thread_q.push(:token)
Thread.new do
begin
while (true)
@@ -112,8 +124,10 @@
trans.close()
end
end
+ rescue Exception => e
+ @exception_q.push(e)
ensure
- @q.pop() # thread died!
+ @thread_q.pop() # thread died!
end
end
end