blob: b44487fd09f19147a938292640290d8589321429 [file] [log] [blame]
David Reiss7f42bcf2008-01-11 20:59:12 +00001//
2// TThreadPoolServer.cs
3//
4// Begin: Dec 3, 2007
David Reiss0c90f6f2008-02-06 22:18:40 +00005// Authors:
David Reiss7f42bcf2008-01-11 20:59:12 +00006// Will Palmeri <wpalmeri@imeem.com>
7//
8// Distributed under the Thrift Software License
9//
10// See accompanying file LICENSE or visit the Thrift site at:
11// http://developers.facebook.com/thrift/using
12using System;
13using System.Collections.Generic;
14using System.Text;
15using System.Threading;
16using Thrift.Protocol;
17using Thrift.Transport;
18
19namespace Thrift.Server
20{
21 /// <summary>
22 /// Server that uses C# built-in ThreadPool to spawn threads when handling requests
23 /// </summary>
24 public class TThreadPoolServer : TServer
25 {
26 private const int DEFAULT_MIN_THREADS = 10;
27 private const int DEFAULT_MAX_THREADS = 100;
David Reissdc815f52008-03-02 00:58:04 +000028 private volatile bool stop = false;
David Reiss7f42bcf2008-01-11 20:59:12 +000029
30 public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport)
31 :this(processor, serverTransport,
32 new TTransportFactory(), new TTransportFactory(),
33 new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
David Reiss63191332009-01-06 19:49:22 +000034 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, DefaultLogDelegate)
David Reiss7f42bcf2008-01-11 20:59:12 +000035 {
36 }
37
David Reiss63191332009-01-06 19:49:22 +000038 public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate)
39 : this(processor, serverTransport,
40 new TTransportFactory(), new TTransportFactory(),
41 new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
42 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, logDelegate)
43 {
44 }
45
46
David Reiss7f42bcf2008-01-11 20:59:12 +000047 public TThreadPoolServer(TProcessor processor,
48 TServerTransport serverTransport,
49 TTransportFactory transportFactory,
50 TProtocolFactory protocolFactory)
51 :this(processor, serverTransport,
52 transportFactory, transportFactory,
53 protocolFactory, protocolFactory,
David Reiss63191332009-01-06 19:49:22 +000054 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS, DefaultLogDelegate)
David Reiss7f42bcf2008-01-11 20:59:12 +000055 {
56 }
57
58 public TThreadPoolServer(TProcessor processor,
59 TServerTransport serverTransport,
60 TTransportFactory inputTransportFactory,
61 TTransportFactory outputTransportFactory,
62 TProtocolFactory inputProtocolFactory,
63 TProtocolFactory outputProtocolFactory,
David Reiss63191332009-01-06 19:49:22 +000064 int minThreadPoolThreads, int maxThreadPoolThreads, LogDelegate logDel)
David Reiss7f42bcf2008-01-11 20:59:12 +000065 :base(processor, serverTransport, inputTransportFactory, outputTransportFactory,
David Reiss63191332009-01-06 19:49:22 +000066 inputProtocolFactory, outputProtocolFactory, logDel)
David Reiss7f42bcf2008-01-11 20:59:12 +000067 {
68 if (!ThreadPool.SetMinThreads(minThreadPoolThreads, minThreadPoolThreads))
69 {
70 throw new Exception("Error: could not SetMinThreads in ThreadPool");
71 }
72 if (!ThreadPool.SetMaxThreads(maxThreadPoolThreads, maxThreadPoolThreads))
73 {
74 throw new Exception("Error: could not SetMaxThreads in ThreadPool");
75 }
David Reiss7f42bcf2008-01-11 20:59:12 +000076 }
77
78 /// <summary>
79 /// Use new ThreadPool thread for each new client connection
80 /// </summary>
81 public override void Serve()
82 {
83 try
84 {
85 serverTransport.Listen();
86 }
87 catch (TTransportException ttx)
88 {
David Reiss63191332009-01-06 19:49:22 +000089 logDelegate("Error, could not listen on ServerTransport: " + ttx);
David Reiss7f42bcf2008-01-11 20:59:12 +000090 return;
91 }
92
David Reissdc815f52008-03-02 00:58:04 +000093 while (!stop)
David Reiss7f42bcf2008-01-11 20:59:12 +000094 {
95 int failureCount = 0;
96 try
97 {
98 TTransport client = serverTransport.Accept();
99 ThreadPool.QueueUserWorkItem(this.Execute, client);
100 }
101 catch (TTransportException ttx)
102 {
David Reiss63191332009-01-06 19:49:22 +0000103 if (stop)
104 {
105 logDelegate("TThreadPoolServer was shutting down, caught " + ttx.GetType().Name);
106 }
107 else
108 {
109 ++failureCount;
110 logDelegate(ttx.ToString());
111 }
112
David Reiss7f42bcf2008-01-11 20:59:12 +0000113 }
114 }
David Reissdc815f52008-03-02 00:58:04 +0000115
116 if (stop)
117 {
118 try
119 {
120 serverTransport.Close();
121 }
122 catch (TTransportException ttx)
123 {
David Reiss63191332009-01-06 19:49:22 +0000124 logDelegate("TServerTransport failed on close: " + ttx.Message);
David Reissdc815f52008-03-02 00:58:04 +0000125 }
126 stop = false;
127 }
128 }
129
David Reiss7f42bcf2008-01-11 20:59:12 +0000130 /// <summary>
131 /// Loops on processing a client forever
132 /// threadContext will be a TTransport instance
133 /// </summary>
134 /// <param name="threadContext"></param>
135 private void Execute(Object threadContext)
136 {
137 TTransport client = (TTransport)threadContext;
138 TTransport inputTransport = null;
139 TTransport outputTransport = null;
140 TProtocol inputProtocol = null;
141 TProtocol outputProtocol = null;
142 try
143 {
144 inputTransport = inputTransportFactory.GetTransport(client);
145 outputTransport = outputTransportFactory.GetTransport(client);
146 inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
147 outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
David Reiss0c90f6f2008-02-06 22:18:40 +0000148 while (processor.Process(inputProtocol, outputProtocol))
David Reiss7f42bcf2008-01-11 20:59:12 +0000149 {
150 //keep processing requests until client disconnects
151 }
152 }
David Reisscee1e082008-04-02 22:10:09 +0000153 catch (TTransportException)
David Reiss7f42bcf2008-01-11 20:59:12 +0000154 {
155 // Assume the client died and continue silently
David Reiss63191332009-01-06 19:49:22 +0000156 //Console.WriteLine(ttx);
David Reiss7f42bcf2008-01-11 20:59:12 +0000157 }
158
159 catch (Exception x)
160 {
David Reiss63191332009-01-06 19:49:22 +0000161 logDelegate("Error: " + x);
David Reiss7f42bcf2008-01-11 20:59:12 +0000162 }
163
164 if (inputTransport != null)
165 {
166 inputTransport.Close();
167 }
168 if (outputTransport != null)
169 {
170 outputTransport.Close();
171 }
172 }
David Reiss63191332009-01-06 19:49:22 +0000173
174 public override void Stop()
175 {
176 stop = true;
177 serverTransport.Close();
178 }
David Reiss7f42bcf2008-01-11 20:59:12 +0000179 }
180}