[thrift] Ruby TThreadedServer and TThreadPoolServer
Summary: They both use the same handler for all connections and thus assume the handler is thread-safe. The TThreadPoolServer preserves threads, so it wouldn't be too hard to make a variant that used a separate handler for each thread and thus didn't require thread safety.
Reviewed By: mcslee
Test Plan: loads without error
Revert Plan: ok
Other Notes: contributed by William Morgan (w@adap.tv)
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665438 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/rb/lib/thrift/server/tserver.rb b/lib/rb/lib/thrift/server/tserver.rb
index 95e6297..6bfc1e0 100644
--- a/lib/rb/lib/thrift/server/tserver.rb
+++ b/lib/rb/lib/thrift/server/tserver.rb
@@ -50,4 +50,72 @@
end
+begin
+ require 'fastthread'
+rescue LoadError
+ require 'thread'
+end
+
+class TThreadedServer < TServer
+ def serve()
+ begin
+ @serverTransport.listen()
+ while (true)
+ client = @serverTransport.accept()
+ trans = @transportFactory.getTransport(client)
+ prot = @protocolFactory.getProtocol(trans)
+ Thread.new(prot, trans) do |p, t|
+ begin
+ while (true)
+ @processor.process(p, p)
+ end
+ rescue TTransportException, TProtocolException => e
+ ensure
+ t.close()
+ end
+ end
+ end
+ ensure
+ @serverTransport.close()
+ end
+ end
+end
+
+class TThreadPoolServer < TServer
+ def initialize(processor, serverTransport, transportFactory=nil, protocolFactory=nil, num=20)
+ super(processor, serverTransport, transportFactory, protocolFactory)
+ @q = SizedQueue.new(num)
+ end
+
+ def serve()
+ @serverTransport.listen()
+
+ begin
+ while (true)
+ @q.push(:token)
+ Thread.new do
+ begin
+ while (true)
+ client = @serverTransport.accept()
+ trans = @transportFactory.getTransport(client)
+ prot = @protocolFactory.getProtocol(trans)
+ begin
+ while (true)
+ @processor.process(prot, prot)
+ end
+ rescue TTransportException, TProtocolException => e
+ ensure
+ trans.close()
+ end
+ end
+ ensure
+ @q.pop() # thread died!
+ end
+ end
+ end
+ ensure
+ @serverTransport.close()
+ end
+ end
+end