| /* |
| * |
| * Copyright 2016 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| #ifndef GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H |
| #define GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H |
| |
| #include <climits> |
| #include <functional> |
| #include <map> |
| #include <memory> |
| #include <vector> |
| |
| #include <grpc/impl/codegen/log.h> |
| #include <grpcpp/impl/codegen/byte_buffer.h> |
| #include <grpcpp/impl/codegen/config.h> |
| #include <grpcpp/impl/codegen/rpc_method.h> |
| #include <grpcpp/impl/codegen/status.h> |
| |
| namespace grpc { |
| class ServerContext; |
| |
| namespace internal { |
| /// Base class for running an RPC handler. |
| class MethodHandler { |
| public: |
| virtual ~MethodHandler() {} |
| struct HandlerParameter { |
| /// Constructor for HandlerParameter |
| /// |
| /// \param c : the gRPC Call structure for this server call |
| /// \param context : the ServerContext structure for this server call |
| /// \param req : the request payload, if appropriate for this RPC |
| /// \param req_status : the request status after any interceptors have run |
| /// \param rpc_requester : used only by the callback API. It is a function |
| /// called by the RPC Controller to request another RPC (and also |
| /// to set up the state required to make that request possible) |
| HandlerParameter(Call* c, ServerContext* context, void* req, |
| Status req_status, std::function<void()> requester) |
| : call(c), |
| server_context(context), |
| request(req), |
| status(req_status), |
| call_requester(std::move(requester)) {} |
| ~HandlerParameter() {} |
| Call* call; |
| ServerContext* server_context; |
| void* request; |
| Status status; |
| std::function<void()> call_requester; |
| }; |
| virtual void RunHandler(const HandlerParameter& param) = 0; |
| |
| /* Returns a pointer to the deserialized request. \a status reflects the |
| result of deserialization. This pointer and the status should be filled in |
| a HandlerParameter and passed to RunHandler. It is illegal to access the |
| pointer after calling RunHandler. Ownership of the deserialized request is |
| retained by the handler. Returns nullptr if deserialization failed. */ |
| virtual void* Deserialize(grpc_call* call, grpc_byte_buffer* req, |
| Status* status) { |
| GPR_CODEGEN_ASSERT(req == nullptr); |
| return nullptr; |
| } |
| }; |
| |
| /// Server side rpc method class |
| class RpcServiceMethod : public RpcMethod { |
| public: |
| /// Takes ownership of the handler |
| RpcServiceMethod(const char* name, RpcMethod::RpcType type, |
| MethodHandler* handler) |
| : RpcMethod(name, type), |
| server_tag_(nullptr), |
| api_type_(ApiType::SYNC), |
| handler_(handler) {} |
| |
| enum class ApiType { |
| SYNC, |
| ASYNC, |
| RAW, |
| CALL_BACK, // not CALLBACK because that is reserved in Windows |
| RAW_CALL_BACK, |
| }; |
| |
| void set_server_tag(void* tag) { server_tag_ = tag; } |
| void* server_tag() const { return server_tag_; } |
| /// if MethodHandler is nullptr, then this is an async method |
| MethodHandler* handler() const { return handler_.get(); } |
| ApiType api_type() const { return api_type_; } |
| void SetHandler(MethodHandler* handler) { handler_.reset(handler); } |
| void SetServerApiType(RpcServiceMethod::ApiType type) { |
| if ((api_type_ == ApiType::SYNC) && |
| (type == ApiType::ASYNC || type == ApiType::RAW)) { |
| // this marks this method as async |
| handler_.reset(); |
| } else if (api_type_ != ApiType::SYNC) { |
| // this is not an error condition, as it allows users to declare a server |
| // like WithRawMethod_foo<AsyncService>. However since it |
| // overwrites behavior, it should be logged. |
| gpr_log( |
| GPR_INFO, |
| "You are marking method %s as '%s', even though it was " |
| "previously marked '%s'. This behavior will overwrite the original " |
| "behavior. If you expected this then ignore this message.", |
| name(), TypeToString(api_type_), TypeToString(type)); |
| } |
| api_type_ = type; |
| } |
| |
| private: |
| void* server_tag_; |
| ApiType api_type_; |
| std::unique_ptr<MethodHandler> handler_; |
| |
| const char* TypeToString(RpcServiceMethod::ApiType type) { |
| switch (type) { |
| case ApiType::SYNC: |
| return "sync"; |
| case ApiType::ASYNC: |
| return "async"; |
| case ApiType::RAW: |
| return "raw"; |
| case ApiType::CALL_BACK: |
| return "callback"; |
| case ApiType::RAW_CALL_BACK: |
| return "raw_callback"; |
| default: |
| GPR_UNREACHABLE_CODE(return "unknown"); |
| } |
| } |
| }; |
| } // namespace internal |
| |
| } // namespace grpc |
| |
| #endif // GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H |