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.protocol.processor; 20 21 // Use selective import once DMD @@BUG314@@ is fixed. 22 import std.variant /+ : Variant +/; 23 import thrift.protocol.base; 24 import thrift.transport.base; 25 26 /** 27 * A processor is a generic object which operates upon an input stream and 28 * writes to some output stream. 29 * 30 * The definition of this object is loose, though the typical case is for some 31 * sort of server that either generates responses to an input stream or 32 * forwards data from one pipe onto another. 33 * 34 * An implementation can optionally allow one or more TProcessorEventHandlers 35 * to be attached, providing an interface to hook custom code into the 36 * handling process, which can be used e.g. for gathering statistics. 37 */ 38 interface TProcessor { 39 /// 40 bool process(TProtocol iprot, TProtocol oprot, 41 Variant connectionContext = Variant() 42 ) in { 43 assert(iprot); 44 assert(oprot); 45 } 46 47 /// 48 final bool process(TProtocol prot, Variant connectionContext = Variant()) { 49 return process(prot, prot, connectionContext); 50 } 51 } 52 53 /** 54 * Handles events from a processor. 55 */ 56 interface TProcessorEventHandler { 57 /** 58 * Called before calling other callback methods. 59 * 60 * Expected to return some sort of »call context«, which is passed to all 61 * other callbacks for that function invocation. 62 */ 63 Variant createContext(string methodName, Variant connectionContext); 64 65 /** 66 * Called when handling the method associated with a context has been 67 * finished – can be used to perform clean up work. 68 */ 69 void deleteContext(Variant callContext, string methodName); 70 71 /** 72 * Called before reading arguments. 73 */ 74 void preRead(Variant callContext, string methodName); 75 76 /** 77 * Called between reading arguments and calling the handler. 78 */ 79 void postRead(Variant callContext, string methodName); 80 81 /** 82 * Called between calling the handler and writing the response. 83 */ 84 void preWrite(Variant callContext, string methodName); 85 86 /** 87 * Called after writing the response. 88 */ 89 void postWrite(Variant callContext, string methodName); 90 91 /** 92 * Called when handling a one-way function call is completed successfully. 93 */ 94 void onewayComplete(Variant callContext, string methodName); 95 96 /** 97 * Called if the handler throws an undeclared exception. 98 */ 99 void handlerError(Variant callContext, string methodName, Exception e); 100 } 101 102 struct TConnectionInfo { 103 /// The input and output protocols. 104 TProtocol input; 105 TProtocol output; /// Ditto. 106 107 /// The underlying transport used for the connection 108 /// This is the transport that was returned by TServerTransport.accept(), 109 /// and it may be different than the transport pointed to by the input and 110 /// output protocols. 111 TTransport transport; 112 } 113 114 interface TProcessorFactory { 115 /** 116 * Get the TProcessor to use for a particular connection. 117 * 118 * This method is always invoked in the same thread that the connection was 119 * accepted on, which is always the same thread for all current server 120 * implementations. 121 */ 122 TProcessor getProcessor(ref const(TConnectionInfo) connInfo); 123 } 124 125 /** 126 * The default processor factory which always returns the same instance. 127 */ 128 class TSingletonProcessorFactory : TProcessorFactory { 129 /** 130 * Creates a new instance. 131 * 132 * Params: 133 * processor = The processor object to return from getProcessor(). 134 */ this(TProcessor processor)135 this(TProcessor processor) { 136 processor_ = processor; 137 } 138 getProcessor(ref const (TConnectionInfo)connInfo)139 override TProcessor getProcessor(ref const(TConnectionInfo) connInfo) { 140 return processor_; 141 } 142 143 private: 144 TProcessor processor_; 145 } 146