1# Copyright 2017 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Common interfaces and implementation.""" 15 16import abc 17import collections 18 19 20def _fuss(tuplified_metadata): 21 return tuplified_metadata + ( 22 ( 23 "grpc.metadata_added_by_runtime", 24 "gRPC is allowed to add metadata in transmission and does so.", 25 ), 26 ) 27 28 29FUSSED_EMPTY_METADATA = _fuss(()) 30 31 32def fuss_with_metadata(metadata): 33 if metadata is None: 34 return FUSSED_EMPTY_METADATA 35 else: 36 return _fuss(tuple(metadata)) 37 38 39def rpc_names(service_descriptors): 40 rpc_names_to_descriptors = {} 41 for service_descriptor in service_descriptors: 42 for method_descriptor in service_descriptor.methods_by_name.values(): 43 rpc_name = "/{}/{}".format( 44 service_descriptor.full_name, method_descriptor.name 45 ) 46 rpc_names_to_descriptors[rpc_name] = method_descriptor 47 return rpc_names_to_descriptors 48 49 50class ChannelRpcRead( 51 collections.namedtuple( 52 "ChannelRpcRead", 53 ( 54 "response", 55 "trailing_metadata", 56 "code", 57 "details", 58 ), 59 ) 60): 61 pass 62 63 64class ChannelRpcHandler(abc.ABC): 65 @abc.abstractmethod 66 def initial_metadata(self): 67 raise NotImplementedError() 68 69 @abc.abstractmethod 70 def add_request(self, request): 71 raise NotImplementedError() 72 73 @abc.abstractmethod 74 def close_requests(self): 75 raise NotImplementedError() 76 77 @abc.abstractmethod 78 def take_response(self): 79 raise NotImplementedError() 80 81 @abc.abstractmethod 82 def cancel(self, code, details): 83 raise NotImplementedError() 84 85 @abc.abstractmethod 86 def termination(self): 87 raise NotImplementedError() 88 89 @abc.abstractmethod 90 def is_active(self): 91 raise NotImplementedError() 92 93 @abc.abstractmethod 94 def time_remaining(self): 95 raise NotImplementedError() 96 97 @abc.abstractmethod 98 def add_callback(self, callback): 99 raise NotImplementedError() 100 101 102class ChannelHandler(abc.ABC): 103 @abc.abstractmethod 104 def invoke_rpc( 105 self, 106 method_full_rpc_name, 107 invocation_metadata, 108 requests, 109 requests_closed, 110 timeout, 111 ): 112 raise NotImplementedError() 113 114 115class ServerRpcRead( 116 collections.namedtuple( 117 "ServerRpcRead", 118 ( 119 "request", 120 "requests_closed", 121 "terminated", 122 ), 123 ) 124): 125 pass 126 127 128REQUESTS_CLOSED = ServerRpcRead(None, True, False) 129TERMINATED = ServerRpcRead(None, False, True) 130 131 132class ServerRpcHandler(abc.ABC): 133 @abc.abstractmethod 134 def send_initial_metadata(self, initial_metadata): 135 raise NotImplementedError() 136 137 @abc.abstractmethod 138 def take_request(self): 139 raise NotImplementedError() 140 141 @abc.abstractmethod 142 def add_response(self, response): 143 raise NotImplementedError() 144 145 @abc.abstractmethod 146 def send_termination(self, trailing_metadata, code, details): 147 raise NotImplementedError() 148 149 @abc.abstractmethod 150 def add_termination_callback(self, callback): 151 raise NotImplementedError() 152 153 154class Serverish(abc.ABC): 155 @abc.abstractmethod 156 def invoke_unary_unary( 157 self, method_descriptor, handler, invocation_metadata, request, deadline 158 ): 159 raise NotImplementedError() 160 161 @abc.abstractmethod 162 def invoke_unary_stream( 163 self, method_descriptor, handler, invocation_metadata, request, deadline 164 ): 165 raise NotImplementedError() 166 167 @abc.abstractmethod 168 def invoke_stream_unary( 169 self, method_descriptor, handler, invocation_metadata, deadline 170 ): 171 raise NotImplementedError() 172 173 @abc.abstractmethod 174 def invoke_stream_stream( 175 self, method_descriptor, handler, invocation_metadata, deadline 176 ): 177 raise NotImplementedError() 178