blob: f8ee355db59519b35ea92616e795068e888ad862 [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(),
34 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS)
35 {
36 }
37
38 public TThreadPoolServer(TProcessor processor,
39 TServerTransport serverTransport,
40 TTransportFactory transportFactory,
41 TProtocolFactory protocolFactory)
42 :this(processor, serverTransport,
43 transportFactory, transportFactory,
44 protocolFactory, protocolFactory,
45 DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS)
46 {
47 }
48
49 public TThreadPoolServer(TProcessor processor,
50 TServerTransport serverTransport,
51 TTransportFactory inputTransportFactory,
52 TTransportFactory outputTransportFactory,
53 TProtocolFactory inputProtocolFactory,
54 TProtocolFactory outputProtocolFactory,
55 int minThreadPoolThreads, int maxThreadPoolThreads)
56 :base(processor, serverTransport, inputTransportFactory, outputTransportFactory,
57 inputProtocolFactory, outputProtocolFactory)
58 {
59 if (!ThreadPool.SetMinThreads(minThreadPoolThreads, minThreadPoolThreads))
60 {
61 throw new Exception("Error: could not SetMinThreads in ThreadPool");
62 }
63 if (!ThreadPool.SetMaxThreads(maxThreadPoolThreads, maxThreadPoolThreads))
64 {
65 throw new Exception("Error: could not SetMaxThreads in ThreadPool");
66 }
67
68 }
69
70 /// <summary>
71 /// Use new ThreadPool thread for each new client connection
72 /// </summary>
73 public override void Serve()
74 {
75 try
76 {
77 serverTransport.Listen();
78 }
79 catch (TTransportException ttx)
80 {
81 Console.Error.WriteLine("Error, could not listen on ServerTransport: " + ttx);
82 return;
83 }
84
David Reissdc815f52008-03-02 00:58:04 +000085 while (!stop)
David Reiss7f42bcf2008-01-11 20:59:12 +000086 {
87 int failureCount = 0;
88 try
89 {
90 TTransport client = serverTransport.Accept();
91 ThreadPool.QueueUserWorkItem(this.Execute, client);
92 }
93 catch (TTransportException ttx)
94 {
95 ++failureCount;
96 Console.Error.WriteLine(ttx);
97 }
98 }
David Reissdc815f52008-03-02 00:58:04 +000099
100 if (stop)
101 {
102 try
103 {
104 serverTransport.Close();
105 }
106 catch (TTransportException ttx)
107 {
108 Console.Error.WriteLine("TServerTrasnport failed on close: " + ttx.Message);
109 }
110 stop = false;
111 }
112 }
113
114
115 public override void Stop()
116 {
117 stop = true;
David Reiss7f42bcf2008-01-11 20:59:12 +0000118 }
119
120 /// <summary>
121 /// Loops on processing a client forever
122 /// threadContext will be a TTransport instance
123 /// </summary>
124 /// <param name="threadContext"></param>
125 private void Execute(Object threadContext)
126 {
127 TTransport client = (TTransport)threadContext;
128 TTransport inputTransport = null;
129 TTransport outputTransport = null;
130 TProtocol inputProtocol = null;
131 TProtocol outputProtocol = null;
132 try
133 {
134 inputTransport = inputTransportFactory.GetTransport(client);
135 outputTransport = outputTransportFactory.GetTransport(client);
136 inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
137 outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
David Reiss0c90f6f2008-02-06 22:18:40 +0000138 while (processor.Process(inputProtocol, outputProtocol))
David Reiss7f42bcf2008-01-11 20:59:12 +0000139 {
140 //keep processing requests until client disconnects
141 }
142 }
143 catch (TTransportException ttx)
144 {
145 // Assume the client died and continue silently
146 }
147
148 catch (Exception x)
149 {
150 Console.Error.WriteLine("Error: " + x);
151 }
152
153 if (inputTransport != null)
154 {
155 inputTransport.Close();
156 }
157 if (outputTransport != null)
158 {
159 outputTransport.Close();
160 }
161 }
162 }
163}