1 /* 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 module thrift.server.base; 20 21 import std.variant : Variant; 22 import thrift.protocol.base; 23 import thrift.protocol.binary; 24 import thrift.protocol.processor; 25 import thrift.server.transport.base; 26 import thrift.transport.base; 27 import thrift.util.cancellation; 28 29 /** 30 * Base class for all Thrift servers. 31 * 32 * By setting the eventHandler property to a TServerEventHandler 33 * implementation, custom code can be integrated into the processing pipeline, 34 * which can be used e.g. for gathering statistics. 35 */ 36 class TServer { 37 /** 38 * Starts serving. 39 * 40 * Blocks until the server finishes, i.e. a serious problem occurred or the 41 * cancellation request has been triggered. 42 * 43 * Server implementations are expected to implement cancellation in a best- 44 * effort way – usually, it should be possible to immediately stop accepting 45 * connections and return after all currently active clients have been 46 * processed, but this might not be the case for every conceivable 47 * implementation. 48 */ 49 abstract void serve(TCancellation cancellation = null); 50 51 /// The server event handler to notify. Null by default. 52 TServerEventHandler eventHandler; 53 54 protected: 55 this( 56 TProcessor processor, 57 TServerTransport serverTransport, 58 TTransportFactory transportFactory, 59 TProtocolFactory protocolFactory 60 ) { 61 this(processor, serverTransport, transportFactory, transportFactory, 62 protocolFactory, protocolFactory); 63 } 64 65 this( 66 TProcessorFactory processorFactory, 67 TServerTransport serverTransport, 68 TTransportFactory transportFactory, 69 TProtocolFactory protocolFactory 70 ) { 71 this(processorFactory, serverTransport, transportFactory, transportFactory, 72 protocolFactory, protocolFactory); 73 } 74 75 this( 76 TProcessor processor, 77 TServerTransport serverTransport, 78 TTransportFactory inputTransportFactory, 79 TTransportFactory outputTransportFactory, 80 TProtocolFactory inputProtocolFactory, 81 TProtocolFactory outputProtocolFactory 82 ) { 83 this(new TSingletonProcessorFactory(processor), serverTransport, 84 inputTransportFactory, outputTransportFactory, 85 inputProtocolFactory, outputProtocolFactory); 86 } 87 88 this( 89 TProcessorFactory processorFactory, 90 TServerTransport serverTransport, 91 TTransportFactory inputTransportFactory, 92 TTransportFactory outputTransportFactory, 93 TProtocolFactory inputProtocolFactory, 94 TProtocolFactory outputProtocolFactory 95 ) { 96 import std.exception; 97 import thrift.base; 98 enforce(inputTransportFactory, 99 new TException("Input transport factory must not be null.")); 100 enforce(outputTransportFactory, 101 new TException("Output transport factory must not be null.")); 102 enforce(inputProtocolFactory, 103 new TException("Input protocol factory must not be null.")); 104 enforce(outputProtocolFactory, 105 new TException("Output protocol factory must not be null.")); 106 107 processorFactory_ = processorFactory; 108 serverTransport_ = serverTransport; 109 inputTransportFactory_ = inputTransportFactory; 110 outputTransportFactory_ = outputTransportFactory; 111 inputProtocolFactory_ = inputProtocolFactory; 112 outputProtocolFactory_ = outputProtocolFactory; 113 } 114 115 TProcessorFactory processorFactory_; 116 TServerTransport serverTransport_; 117 TTransportFactory inputTransportFactory_; 118 TTransportFactory outputTransportFactory_; 119 TProtocolFactory inputProtocolFactory_; 120 TProtocolFactory outputProtocolFactory_; 121 122 public: 123 124 @property TProcessorFactory processorFactory() 125 { 126 return processorFactory_; 127 } 128 129 @property TServerTransport serverTransport() 130 { 131 return serverTransport_; 132 } 133 134 @property TTransportFactory inputTransportFactory() 135 { 136 return inputTransportFactory_; 137 } 138 139 @property TTransportFactory outputTransportFactory() 140 { 141 return outputTransportFactory_; 142 } 143 144 @property TProtocolFactory inputProtocolFactory() 145 { 146 return inputProtocolFactory_; 147 } 148 149 @property TProtocolFactory outputProtocolFactory() 150 { 151 return outputProtocolFactory_; 152 } 153 } 154 155 /** 156 * Handles events from a TServer core. 157 */ 158 interface TServerEventHandler { 159 /** 160 * Called before the server starts accepting connections. 161 */ 162 void preServe(); 163 164 /** 165 * Called when a new client has connected and processing is about to begin. 166 */ 167 Variant createContext(TProtocol input, TProtocol output); 168 169 /** 170 * Called when request handling for a client has been finished – can be used 171 * to perform clean up work. 172 */ 173 void deleteContext(Variant serverContext, TProtocol input, TProtocol output); 174 175 /** 176 * Called when the processor for a client call is about to be invoked. 177 */ 178 void preProcess(Variant serverContext, TTransport transport); 179 }