1 /* 2 * 3 * Copyright 2016 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H 20 #define GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H 21 22 #include <climits> 23 #include <functional> 24 #include <map> 25 #include <memory> 26 #include <vector> 27 28 #include <grpc/impl/codegen/log.h> 29 #include <grpcpp/impl/codegen/byte_buffer.h> 30 #include <grpcpp/impl/codegen/config.h> 31 #include <grpcpp/impl/codegen/rpc_method.h> 32 #include <grpcpp/impl/codegen/status.h> 33 34 namespace grpc { 35 class ServerContext; 36 37 namespace internal { 38 /// Base class for running an RPC handler. 39 class MethodHandler { 40 public: ~MethodHandler()41 virtual ~MethodHandler() {} 42 struct HandlerParameter { HandlerParameterHandlerParameter43 HandlerParameter(Call* c, ServerContext* context, grpc_byte_buffer* req) 44 : call(c), server_context(context) { 45 request.set_buffer(req); 46 } ~HandlerParameterHandlerParameter47 ~HandlerParameter() { request.Release(); } 48 Call* call; 49 ServerContext* server_context; 50 // Handler required to destroy these contents 51 ByteBuffer request; 52 }; 53 virtual void RunHandler(const HandlerParameter& param) = 0; 54 }; 55 56 /// Server side rpc method class 57 class RpcServiceMethod : public RpcMethod { 58 public: 59 /// Takes ownership of the handler RpcServiceMethod(const char * name,RpcMethod::RpcType type,MethodHandler * handler)60 RpcServiceMethod(const char* name, RpcMethod::RpcType type, 61 MethodHandler* handler) 62 : RpcMethod(name, type), 63 server_tag_(nullptr), 64 async_type_(AsyncType::UNSET), 65 handler_(handler) {} 66 67 enum class AsyncType { 68 UNSET, 69 ASYNC, 70 RAW, 71 }; 72 set_server_tag(void * tag)73 void set_server_tag(void* tag) { server_tag_ = tag; } server_tag()74 void* server_tag() const { return server_tag_; } 75 /// if MethodHandler is nullptr, then this is an async method handler()76 MethodHandler* handler() const { return handler_.get(); } SetHandler(MethodHandler * handler)77 void SetHandler(MethodHandler* handler) { handler_.reset(handler); } SetServerAsyncType(RpcServiceMethod::AsyncType type)78 void SetServerAsyncType(RpcServiceMethod::AsyncType type) { 79 if (async_type_ == AsyncType::UNSET) { 80 // this marks this method as async 81 handler_.reset(); 82 } else { 83 // this is not an error condition, as it allows users to declare a server 84 // like WithRawMethod_foo<AsyncService>. However since it 85 // overwrites behavior, it should be logged. 86 gpr_log( 87 GPR_INFO, 88 "You are marking method %s as '%s', even though it was " 89 "previously marked '%s'. This behavior will overwrite the original " 90 "behavior. If you expected this then ignore this message.", 91 name(), TypeToString(async_type_), TypeToString(type)); 92 } 93 async_type_ = type; 94 } 95 96 private: 97 void* server_tag_; 98 AsyncType async_type_; 99 std::unique_ptr<MethodHandler> handler_; 100 TypeToString(RpcServiceMethod::AsyncType type)101 const char* TypeToString(RpcServiceMethod::AsyncType type) { 102 switch (type) { 103 case AsyncType::UNSET: 104 return "unset"; 105 case AsyncType::ASYNC: 106 return "async"; 107 case AsyncType::RAW: 108 return "raw"; 109 default: 110 GPR_UNREACHABLE_CODE(return "unknown"); 111 } 112 } 113 }; 114 } // namespace internal 115 116 } // namespace grpc 117 118 #endif // GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H 119