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