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.transport.base;
20 version(NeedTServer):
21 import thrift.base;
22 import thrift.transport.base;
23 import thrift.util.cancellation;
24 
25 /**
26  * Some kind of I/O device enabling servers to listen for incoming client
27  * connections and communicate with them via a TTransport interface.
28  */
29 interface TServerTransport {
30   /**
31    * Starts listening for server connections.
32    *
33    * Just as simliar functions commonly found in socket libraries, this
34    * function does not block.
35    *
36    * If the socket is already listening, nothing happens.
37    *
38    * Throws: TServerTransportException if listening failed or the transport
39    *   was already listening.
40    */
41   void listen();
42 
43   /**
44    * Closes the server transport, causing it to stop listening.
45    *
46    * Throws: TServerTransportException if the transport was not listening.
47    */
48   void close();
49 
50   /**
51    * Returns whether the server transport is currently listening.
52    */
53   bool isListening() @property;
54 
55   /**
56    * Accepts a client connection and returns an opened TTransport for it,
57    * never returning null.
58    *
59    * Blocks until a client connection is available.
60    *
61    * Params:
62    *   cancellation = If triggered, requests the call to stop blocking and
63    *     return with a TCancelledException. Implementations are free to
64    *     ignore this if they cannot provide a reasonable.
65    *
66    * Throws: TServerTransportException if accepting failed,
67    *   TCancelledException if it was cancelled.
68    */
69   TTransport accept(TCancellation cancellation = null) out (result) {
70     assert(result !is null);
71   }
72 }
73 
74 /**
75  * Server transport exception.
76  */
77 class TServerTransportException : TException {
78   /**
79    * Error codes for the various types of exceptions.
80    */
81   enum Type {
82     ///
83     UNKNOWN,
84 
85     /// The server socket is not listening, but excepted to be.
86     NOT_LISTENING,
87 
88     /// The server socket is already listening, but expected not to be.
89     ALREADY_LISTENING,
90 
91     /// An operation on the primary underlying resource, e.g. a socket used
92     /// for accepting connections, failed.
93     RESOURCE_FAILED
94   }
95 
96   ///
97   this(Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
98     import std.algorithm:predSwitch;
99     string msg = "TTransportException: ";
100 
101     // cannot call constructor after labels in new dmd
102 
103     msg ~= type.predSwitch!"a==b"(
104       		Type.UNKNOWN,            "Unknown server transport exception",
105       		Type.NOT_LISTENING,      "Server transport not listening",
106       		Type.ALREADY_LISTENING,  "Server transport already listening",
107                 Type.RESOURCE_FAILED,    "An underlying resource failed",
108 	                                 "(Invalid exception type)"
109 		);
110     this(msg, type, file, line, next);
111   }
112 
113   ///
114   this(string msg, string file = __FILE__, size_t line = __LINE__,
115     Throwable next = cast(Throwable) null)
116   {
117     this(msg, Type.UNKNOWN, file, line, next);
118   }
119 
120   ///
121   this(string msg, Type type, string file = __FILE__, size_t line = __LINE__,
122     Throwable next = cast(Throwable) null)
123   {
124     super(msg, file, line, next);
125     type_ = type;
126   }
127 
128   ///
129   Type type() const nothrow @property {
130     return type_;
131   }
132 
133 protected:
134   Type type_;
135 }
136