add additional entrypoint to TThreadPoolServer with easy exception handling
authorKevin Clark <kclark@apache.org>
Wed, 18 Jun 2008 00:49:38 +0000 (00:49 +0000)
committerKevin Clark <kclark@apache.org>
Wed, 18 Jun 2008 00:49:38 +0000 (00:49 +0000)
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

lib/rb/lib/thrift/server/tserver.rb

index 43b2bdd..f2239c8 100644 (file)
@@ -88,15 +88,27 @@ end
 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 @@ class TThreadPoolServer < TServer
                 trans.close()
               end
             end
+          rescue Exception => e
+            @exception_q.push(e)
           ensure
-            @q.pop() # thread died!
+            @thread_q.pop() # thread died!
           end
         end
       end