blob: 6d3ff3855cd50ea3c0f41139fef9d0d511a47bc3 [file] [log] [blame]
Jake Farrell27274222011-11-10 20:32:44 +00001(*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *)
19
20 unit Thrift.Server;
21
Jens Geyer26ef7432013-09-23 22:01:20 +020022{$I-} // prevent annoying errors with default log delegate and no console
23
Jake Farrell27274222011-11-10 20:32:44 +000024interface
25
26uses
Jens Geyer26ef7432013-09-23 22:01:20 +020027 Windows, SysUtils,
Jake Farrell27274222011-11-10 20:32:44 +000028 Thrift,
29 Thrift.Protocol,
30 Thrift.Transport;
31
32type
33 IServer = interface
34 ['{CF9F56C6-BB39-4C7D-877B-43B416572CE6}']
35 procedure Serve;
36 procedure Stop;
37 end;
38
39 TServerImpl = class abstract( TInterfacedObject, IServer )
40 public
41 type
Roger Meier333bbf32012-01-08 21:51:08 +000042 TLogDelegate = reference to procedure( const str: string);
Jake Farrell27274222011-11-10 20:32:44 +000043 protected
44 FProcessor : IProcessor;
45 FServerTransport : IServerTransport;
46 FInputTransportFactory : ITransportFactory;
47 FOutputTransportFactory : ITransportFactory;
48 FInputProtocolFactory : IProtocolFactory;
49 FOutputProtocolFactory : IProtocolFactory;
50 FLogDelegate : TLogDelegate;
51
Roger Meier333bbf32012-01-08 21:51:08 +000052 class procedure DefaultLogDelegate( const str: string);
Jake Farrell27274222011-11-10 20:32:44 +000053
54 procedure Serve; virtual; abstract;
55 procedure Stop; virtual; abstract;
56 public
57 constructor Create(
Roger Meier333bbf32012-01-08 21:51:08 +000058 const AProcessor :IProcessor;
59 const AServerTransport: IServerTransport;
60 const AInputTransportFactory : ITransportFactory;
61 const AOutputTransportFactory : ITransportFactory;
62 const AInputProtocolFactory : IProtocolFactory;
63 const AOutputProtocolFactory : IProtocolFactory;
64 const ALogDelegate : TLogDelegate
Jake Farrell27274222011-11-10 20:32:44 +000065 ); overload;
66
Roger Meier333bbf32012-01-08 21:51:08 +000067 constructor Create(
68 const AProcessor :IProcessor;
69 const AServerTransport: IServerTransport
70 ); overload;
Jake Farrell27274222011-11-10 20:32:44 +000071
72 constructor Create(
Roger Meier333bbf32012-01-08 21:51:08 +000073 const AProcessor :IProcessor;
74 const AServerTransport: IServerTransport;
75 const ALogDelegate: TLogDelegate
Jake Farrell27274222011-11-10 20:32:44 +000076 ); overload;
77
78 constructor Create(
Roger Meier333bbf32012-01-08 21:51:08 +000079 const AProcessor :IProcessor;
80 const AServerTransport: IServerTransport;
81 const ATransportFactory : ITransportFactory
Jake Farrell27274222011-11-10 20:32:44 +000082 ); overload;
83
84 constructor Create(
Roger Meier333bbf32012-01-08 21:51:08 +000085 const AProcessor :IProcessor;
86 const AServerTransport: IServerTransport;
87 const ATransportFactory : ITransportFactory;
88 const AProtocolFactory : IProtocolFactory
Jake Farrell27274222011-11-10 20:32:44 +000089 ); overload;
90 end;
91
92 TSimpleServer = class( TServerImpl)
93 private
94 FStop : Boolean;
95 public
Roger Meier333bbf32012-01-08 21:51:08 +000096 constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport); overload;
97 constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport;
Jake Farrell27274222011-11-10 20:32:44 +000098 ALogDel: TServerImpl.TLogDelegate); overload;
Roger Meier333bbf32012-01-08 21:51:08 +000099 constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport;
100 const ATransportFactory: ITransportFactory); overload;
101 constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport;
102 const ATransportFactory: ITransportFactory; const AProtocolFactory: IProtocolFactory); overload;
Jake Farrell27274222011-11-10 20:32:44 +0000103
104 procedure Serve; override;
105 procedure Stop; override;
106 end;
107
108
109implementation
110
111{ TServerImpl }
112
Roger Meier333bbf32012-01-08 21:51:08 +0000113constructor TServerImpl.Create( const AProcessor: IProcessor;
114 const AServerTransport: IServerTransport; const ALogDelegate: TLogDelegate);
Jake Farrell27274222011-11-10 20:32:44 +0000115var
116 InputFactory, OutputFactory : IProtocolFactory;
117 InputTransFactory, OutputTransFactory : ITransportFactory;
118
119begin
120 InputFactory := TBinaryProtocolImpl.TFactory.Create;
121 OutputFactory := TBinaryProtocolImpl.TFactory.Create;
122 InputTransFactory := TTransportFactoryImpl.Create;
123 OutputTransFactory := TTransportFactoryImpl.Create;
124
Jens Geyer718f6ee2013-09-06 21:02:34 +0200125 //no inherited;
Jake Farrell27274222011-11-10 20:32:44 +0000126 Create(
127 AProcessor,
128 AServerTransport,
129 InputTransFactory,
130 OutputTransFactory,
131 InputFactory,
132 OutputFactory,
133 ALogDelegate
134 );
135end;
136
Roger Meier333bbf32012-01-08 21:51:08 +0000137constructor TServerImpl.Create(const AProcessor: IProcessor;
138 const AServerTransport: IServerTransport);
Jake Farrell27274222011-11-10 20:32:44 +0000139var
140 InputFactory, OutputFactory : IProtocolFactory;
141 InputTransFactory, OutputTransFactory : ITransportFactory;
142
143begin
144 InputFactory := TBinaryProtocolImpl.TFactory.Create;
145 OutputFactory := TBinaryProtocolImpl.TFactory.Create;
146 InputTransFactory := TTransportFactoryImpl.Create;
147 OutputTransFactory := TTransportFactoryImpl.Create;
148
Jens Geyer718f6ee2013-09-06 21:02:34 +0200149 //no inherited;
Jake Farrell27274222011-11-10 20:32:44 +0000150 Create(
151 AProcessor,
152 AServerTransport,
153 InputTransFactory,
154 OutputTransFactory,
155 InputFactory,
156 OutputFactory,
157 DefaultLogDelegate
158 );
159end;
160
Roger Meier333bbf32012-01-08 21:51:08 +0000161constructor TServerImpl.Create(const AProcessor: IProcessor;
162 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory);
Jake Farrell27274222011-11-10 20:32:44 +0000163var
164 InputProtocolFactory : IProtocolFactory;
165 OutputProtocolFactory : IProtocolFactory;
166begin
167 InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
168 OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
169
Jens Geyer718f6ee2013-09-06 21:02:34 +0200170 //no inherited;
Jake Farrell27274222011-11-10 20:32:44 +0000171 Create( AProcessor, AServerTransport, ATransportFactory, ATransportFactory,
172 InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate);
173end;
174
Roger Meier333bbf32012-01-08 21:51:08 +0000175constructor TServerImpl.Create(const AProcessor: IProcessor;
176 const AServerTransport: IServerTransport;
177 const AInputTransportFactory, AOutputTransportFactory: ITransportFactory;
178 const AInputProtocolFactory, AOutputProtocolFactory: IProtocolFactory;
179 const ALogDelegate : TLogDelegate);
Jake Farrell27274222011-11-10 20:32:44 +0000180begin
Jens Geyer718f6ee2013-09-06 21:02:34 +0200181 inherited Create;
Jake Farrell27274222011-11-10 20:32:44 +0000182 FProcessor := AProcessor;
183 FServerTransport := AServerTransport;
184 FInputTransportFactory := AInputTransportFactory;
185 FOutputTransportFactory := AOutputTransportFactory;
186 FInputProtocolFactory := AInputProtocolFactory;
187 FOutputProtocolFactory := AOutputProtocolFactory;
188 FLogDelegate := ALogDelegate;
189end;
190
Roger Meier333bbf32012-01-08 21:51:08 +0000191class procedure TServerImpl.DefaultLogDelegate( const str: string);
Jake Farrell27274222011-11-10 20:32:44 +0000192begin
Jens Geyer26ef7432013-09-23 22:01:20 +0200193 try
194 Writeln( str);
195 if IoResult <> 0 then OutputDebugString(PChar(str));
196 except
197 OutputDebugString(PChar(str));
198 end;
Jake Farrell27274222011-11-10 20:32:44 +0000199end;
200
Roger Meier333bbf32012-01-08 21:51:08 +0000201constructor TServerImpl.Create( const AProcessor: IProcessor;
202 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory;
203 const AProtocolFactory: IProtocolFactory);
Jake Farrell806d2982011-10-26 02:33:31 +0000204begin
Jens Geyer718f6ee2013-09-06 21:02:34 +0200205 //no inherited;
Jake Farrell806d2982011-10-26 02:33:31 +0000206 Create( AProcessor, AServerTransport,
207 ATransportFactory, ATransportFactory,
208 AProtocolFactory, AProtocolFactory,
209 DefaultLogDelegate);
210end;
211
212{ TSimpleServer }
Jake Farrell27274222011-11-10 20:32:44 +0000213
Roger Meier333bbf32012-01-08 21:51:08 +0000214constructor TSimpleServer.Create( const AProcessor: IProcessor;
215 const AServerTransport: IServerTransport);
Jake Farrell27274222011-11-10 20:32:44 +0000216var
217 InputProtocolFactory : IProtocolFactory;
218 OutputProtocolFactory : IProtocolFactory;
219 InputTransportFactory : ITransportFactory;
220 OutputTransportFactory : ITransportFactory;
221begin
222 InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
223 OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
224 InputTransportFactory := TTransportFactoryImpl.Create;
225 OutputTransportFactory := TTransportFactoryImpl.Create;
226
227 inherited Create( AProcessor, AServerTransport, InputTransportFactory,
228 OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate);
229end;
230
Roger Meier333bbf32012-01-08 21:51:08 +0000231constructor TSimpleServer.Create( const AProcessor: IProcessor;
232 const AServerTransport: IServerTransport; ALogDel: TServerImpl.TLogDelegate);
Jake Farrell27274222011-11-10 20:32:44 +0000233var
234 InputProtocolFactory : IProtocolFactory;
235 OutputProtocolFactory : IProtocolFactory;
236 InputTransportFactory : ITransportFactory;
237 OutputTransportFactory : ITransportFactory;
238begin
239 InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
240 OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
241 InputTransportFactory := TTransportFactoryImpl.Create;
242 OutputTransportFactory := TTransportFactoryImpl.Create;
243
244 inherited Create( AProcessor, AServerTransport, InputTransportFactory,
245 OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, ALogDel);
246end;
247
Roger Meier333bbf32012-01-08 21:51:08 +0000248constructor TSimpleServer.Create( const AProcessor: IProcessor;
249 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory);
Jake Farrell27274222011-11-10 20:32:44 +0000250begin
251 inherited Create( AProcessor, AServerTransport, ATransportFactory,
252 ATransportFactory, TBinaryProtocolImpl.TFactory.Create, TBinaryProtocolImpl.TFactory.Create, DefaultLogDelegate);
253end;
254
Roger Meier333bbf32012-01-08 21:51:08 +0000255constructor TSimpleServer.Create( const AProcessor: IProcessor;
256 const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory;
257 const AProtocolFactory: IProtocolFactory);
Jake Farrell27274222011-11-10 20:32:44 +0000258begin
259 inherited Create( AProcessor, AServerTransport, ATransportFactory,
260 ATransportFactory, AProtocolFactory, AProtocolFactory, DefaultLogDelegate);
261end;
262
263procedure TSimpleServer.Serve;
264var
265 client : ITransport;
266 InputTransport : ITransport;
267 OutputTransport : ITransport;
268 InputProtocol : IProtocol;
269 OutputProtocol : IProtocol;
270begin
271 try
272 FServerTransport.Listen;
273 except
274 on E: Exception do
275 begin
276 FLogDelegate( E.ToString);
277 end;
278 end;
279
280 client := nil;
Jake Farrell27274222011-11-10 20:32:44 +0000281 while (not FStop) do
282 begin
283 try
Jens Geyer06045cf2013-03-27 20:26:25 +0200284 // clean up any old instances before waiting for clients
285 InputTransport := nil;
286 OutputTransport := nil;
287 InputProtocol := nil;
288 OutputProtocol := nil;
289
Jake Farrell27274222011-11-10 20:32:44 +0000290 client := FServerTransport.Accept;
291 FLogDelegate( 'Client Connected!');
Jens Geyer06045cf2013-03-27 20:26:25 +0200292
Jake Farrell27274222011-11-10 20:32:44 +0000293 InputTransport := FInputTransportFactory.GetTransport( client );
294 OutputTransport := FOutputTransportFactory.GetTransport( client );
295 InputProtocol := FInputProtocolFactory.GetProtocol( InputTransport );
296 OutputProtocol := FOutputProtocolFactory.GetProtocol( OutputTransport );
297 while ( FProcessor.Process( InputProtocol, OutputProtocol )) do
298 begin
299 if FStop then Break;
300 end;
Jens Geyer06045cf2013-03-27 20:26:25 +0200301
Jake Farrell27274222011-11-10 20:32:44 +0000302 except
303 on E: TTransportException do
304 begin
Roger Meier79655fb2012-10-20 20:59:41 +0000305 if FStop
306 then FLogDelegate('TSimpleServer was shutting down, caught ' + E.ToString)
307 else FLogDelegate( E.ToString);
Jake Farrell27274222011-11-10 20:32:44 +0000308 end;
309 on E: Exception do
310 begin
Roger Meier79655fb2012-10-20 20:59:41 +0000311 FLogDelegate( E.ToString);
Jake Farrell27274222011-11-10 20:32:44 +0000312 end;
313 end;
314 if InputTransport <> nil then
315 begin
316 InputTransport.Close;
317 end;
318 if OutputTransport <> nil then
319 begin
320 OutputTransport.Close;
321 end;
322 end;
323
324 if FStop then
325 begin
326 try
327 FServerTransport.Close;
328 except
329 on E: TTransportException do
330 begin
331 FLogDelegate('TServerTranport failed on close: ' + E.Message);
332 end;
333 end;
334 FStop := False;
335 end;
336end;
337
338procedure TSimpleServer.Stop;
339begin
340 FStop := True;
341 FServerTransport.Close;
342end;
343
344end.