blob: d6b9cd0765825f4815c99fc583dc9c5ae70d55e4 [file] [log] [blame]
Roger Meier6cf0ffc2014-04-05 00:45:42 +02001--
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
20require 'Thrift'
21require 'TFramedTransport'
22require 'TBinaryProtocol'
23
24-- TServer
25TServer = __TObject:new{
26 __type = 'TServer'
27}
28
29-- 2 possible constructors
30-- 1. {processor, serverTransport}
31-- 2. {processor, serverTransport, transportFactory, protocolFactory}
32function TServer:new(args)
33 if ttype(args) ~= 'table' then
34 error('TServer must be initialized with a table')
35 end
36 if args.processor == nil then
37 terror('You must provide ' .. ttype(self) .. ' with a processor')
38 end
39 if args.serverTransport == nil then
40 terror('You must provide ' .. ttype(self) .. ' with a serverTransport')
41 end
42
43 -- Create the object
44 local obj = __TObject.new(self, args)
45
46 if obj.transportFactory then
47 obj.inputTransportFactory = obj.transportFactory
48 obj.outputTransportFactory = obj.transportFactory
49 obj.transportFactory = nil
50 else
51 obj.inputTransportFactory = TFramedTransportFactory:new{}
52 obj.outputTransportFactory = obj.inputTransportFactory
53 end
54
55 if obj.protocolFactory then
56 obj.inputProtocolFactory = obj.protocolFactory
57 obj.outputProtocolFactory = obj.protocolFactory
58 obj.protocolFactory = nil
59 else
60 obj.inputProtocolFactory = TBinaryProtocolFactory:new{}
61 obj.outputProtocolFactory = obj.inputProtocolFactory
62 end
63
64 -- Set the __server variable in the handler so we can stop the server
65 obj.processor.handler.__server = self
66
67 return obj
68end
69
70function TServer:setServerEventHandler(handler)
71 self.serverEventHandler = handler
72end
73
74function TServer:_clientBegin(content, iprot, oprot)
75 if self.serverEventHandler and
76 type(self.serverEventHandler.clientBegin) == 'function' then
77 self.serverEventHandler:clientBegin(iprot, oprot)
78 end
79end
80
81function TServer:_preServe()
82 if self.serverEventHandler and
83 type(self.serverEventHandler.preServe) == 'function' then
84 self.serverEventHandler:preServe(self.serverTransport:getSocketInfo())
85 end
86end
87
88function TServer:_handleException(err)
89 if string.find(err, 'TTransportException') == nil then
90 print(err)
91 end
92end
93
94function TServer:serve() end
95function TServer:handle(client)
96 local itrans, otrans, iprot, oprot, ret, err =
97 self.inputTransportFactory:getTransport(client),
98 self.outputTransportFactory:getTransport(client),
99 self.inputProtocolFactory:getProtocol(client),
100 self.outputProtocolFactory:getProtocol(client)
101
102 self:_clientBegin(iprot, oprot)
103 while true do
104 ret, err = pcall(self.processor.process, self.processor, iprot, oprot)
105 if ret == false and err then
106 if not string.find(err, "TTransportException") then
107 self:_handleException(err)
108 end
109 break
110 end
111 end
112 itrans:close()
113 otrans:close()
114end
115
116function TServer:close()
117 self.serverTransport:close()
118end
119
120-- TSimpleServer
121-- Single threaded server that handles one transport (connection)
122TSimpleServer = __TObject:new(TServer, {
123 __type = 'TSimpleServer',
124 __stop = false
125})
126
127function TSimpleServer:serve()
128 self.serverTransport:listen()
129 self:_preServe()
130 while not self.__stop do
131 client = self.serverTransport:accept()
132 self:handle(client)
133 end
134 self:close()
135end
136
137function TSimpleServer:stop()
138 self.__stop = true
139end