blob: a54d804168f4bd121d27f354618fea61432b9056 [file] [log] [blame]
Jens Geyer0e87c462013-06-18 22:25:07 +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
20package thrift
21
22import (
23 "log"
Jens Geyer91cfb992014-05-17 01:07:28 +020024 "runtime/debug"
Jens Geyer0e87c462013-06-18 22:25:07 +020025)
26
27// Simple, non-concurrent server for testing.
28type TSimpleServer struct {
Jens Geyerc975bbc2014-03-06 21:11:46 +010029 quit chan struct{}
Jens Geyer0e87c462013-06-18 22:25:07 +020030
31 processorFactory TProcessorFactory
32 serverTransport TServerTransport
33 inputTransportFactory TTransportFactory
34 outputTransportFactory TTransportFactory
35 inputProtocolFactory TProtocolFactory
36 outputProtocolFactory TProtocolFactory
37}
38
39func NewTSimpleServer2(processor TProcessor, serverTransport TServerTransport) *TSimpleServer {
40 return NewTSimpleServerFactory2(NewTProcessorFactory(processor), serverTransport)
41}
42
43func NewTSimpleServer4(processor TProcessor, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer {
44 return NewTSimpleServerFactory4(NewTProcessorFactory(processor),
45 serverTransport,
46 transportFactory,
47 protocolFactory,
48 )
49}
50
51func NewTSimpleServer6(processor TProcessor, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer {
52 return NewTSimpleServerFactory6(NewTProcessorFactory(processor),
53 serverTransport,
54 inputTransportFactory,
55 outputTransportFactory,
56 inputProtocolFactory,
57 outputProtocolFactory,
58 )
59}
60
61func NewTSimpleServerFactory2(processorFactory TProcessorFactory, serverTransport TServerTransport) *TSimpleServer {
62 return NewTSimpleServerFactory6(processorFactory,
63 serverTransport,
64 NewTTransportFactory(),
65 NewTTransportFactory(),
66 NewTBinaryProtocolFactoryDefault(),
67 NewTBinaryProtocolFactoryDefault(),
68 )
69}
70
71func NewTSimpleServerFactory4(processorFactory TProcessorFactory, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer {
72 return NewTSimpleServerFactory6(processorFactory,
73 serverTransport,
74 transportFactory,
75 transportFactory,
76 protocolFactory,
77 protocolFactory,
78 )
79}
80
81func NewTSimpleServerFactory6(processorFactory TProcessorFactory, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer {
Jens Geyerc975bbc2014-03-06 21:11:46 +010082 return &TSimpleServer{
83 processorFactory: processorFactory,
Jens Geyer0e87c462013-06-18 22:25:07 +020084 serverTransport: serverTransport,
85 inputTransportFactory: inputTransportFactory,
86 outputTransportFactory: outputTransportFactory,
87 inputProtocolFactory: inputProtocolFactory,
88 outputProtocolFactory: outputProtocolFactory,
Jens Geyerc975bbc2014-03-06 21:11:46 +010089 quit: make(chan struct{}, 1),
Jens Geyer0e87c462013-06-18 22:25:07 +020090 }
91}
92
93func (p *TSimpleServer) ProcessorFactory() TProcessorFactory {
94 return p.processorFactory
95}
96
97func (p *TSimpleServer) ServerTransport() TServerTransport {
98 return p.serverTransport
99}
100
101func (p *TSimpleServer) InputTransportFactory() TTransportFactory {
102 return p.inputTransportFactory
103}
104
105func (p *TSimpleServer) OutputTransportFactory() TTransportFactory {
106 return p.outputTransportFactory
107}
108
109func (p *TSimpleServer) InputProtocolFactory() TProtocolFactory {
110 return p.inputProtocolFactory
111}
112
113func (p *TSimpleServer) OutputProtocolFactory() TProtocolFactory {
114 return p.outputProtocolFactory
115}
116
Jens Geyerf4598682014-05-08 23:18:44 +0200117func (p *TSimpleServer) Listen() error {
118 return p.serverTransport.Listen()
119}
Jens Geyerc975bbc2014-03-06 21:11:46 +0100120
Jens Geyerf4598682014-05-08 23:18:44 +0200121func (p *TSimpleServer) AcceptLoop() error {
Jens Geyerc975bbc2014-03-06 21:11:46 +0100122 for {
Jens Geyer0e87c462013-06-18 22:25:07 +0200123 client, err := p.serverTransport.Accept()
124 if err != nil {
Jens Geyer57cd4212014-12-08 21:25:00 +0100125 select {
126 case <-p.quit:
127 return nil
128 default:
129 }
130 return err
Jens Geyer0e87c462013-06-18 22:25:07 +0200131 }
132 if client != nil {
Jens Geyer7d952462013-07-26 01:01:11 +0200133 go func() {
Jens Geyer91cfb992014-05-17 01:07:28 +0200134 if err := p.processRequests(client); err != nil {
Jens Geyer7d952462013-07-26 01:01:11 +0200135 log.Println("error processing request:", err)
136 }
137 }()
Jens Geyer0e87c462013-06-18 22:25:07 +0200138 }
139 }
Jens Geyerf4598682014-05-08 23:18:44 +0200140}
141
142func (p *TSimpleServer) Serve() error {
143 err := p.Listen()
144 if err != nil {
145 return err
146 }
147 p.AcceptLoop()
Jens Geyer0e87c462013-06-18 22:25:07 +0200148 return nil
149}
150
151func (p *TSimpleServer) Stop() error {
Jens Geyerc975bbc2014-03-06 21:11:46 +0100152 p.quit <- struct{}{}
Jens Geyer0e87c462013-06-18 22:25:07 +0200153 p.serverTransport.Interrupt()
154 return nil
155}
156
Jens Geyer91cfb992014-05-17 01:07:28 +0200157func (p *TSimpleServer) processRequests(client TTransport) error {
Jens Geyer0e87c462013-06-18 22:25:07 +0200158 processor := p.processorFactory.GetProcessor(client)
159 inputTransport := p.inputTransportFactory.GetTransport(client)
160 outputTransport := p.outputTransportFactory.GetTransport(client)
161 inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport)
162 outputProtocol := p.outputProtocolFactory.GetProtocol(outputTransport)
Jens Geyer91cfb992014-05-17 01:07:28 +0200163 defer func() {
164 if e := recover(); e != nil {
165 log.Printf("panic in processor: %s: %s", e, debug.Stack())
166 }
167 }()
Jens Geyer0e87c462013-06-18 22:25:07 +0200168 if inputTransport != nil {
169 defer inputTransport.Close()
170 }
171 if outputTransport != nil {
172 defer outputTransport.Close()
173 }
174 for {
175 ok, err := processor.Process(inputProtocol, outputProtocol)
Jens Geyerf4598682014-05-08 23:18:44 +0200176 if err, ok := err.(TTransportException); ok && err.TypeId() == END_OF_FILE {
Jens Geyer0e87c462013-06-18 22:25:07 +0200177 return nil
178 } else if err != nil {
Jens Geyer91cfb992014-05-17 01:07:28 +0200179 log.Printf("error processing request: %s", err)
Jens Geyer0e87c462013-06-18 22:25:07 +0200180 return err
181 }
Jens Geyer09972502014-05-02 01:30:13 +0200182 if !ok {
Jens Geyer0e87c462013-06-18 22:25:07 +0200183 break
184 }
185 }
186 return nil
187}