Home | History | Annotate | Download | only in codegen
      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:
     41   virtual ~MethodHandler() {}
     42   struct HandlerParameter {
     43     HandlerParameter(Call* c, ServerContext* context, grpc_byte_buffer* req)
     44         : call(c), server_context(context) {
     45       request.set_buffer(req);
     46     }
     47     ~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
     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 
     73   void set_server_tag(void* tag) { server_tag_ = tag; }
     74   void* server_tag() const { return server_tag_; }
     75   /// if MethodHandler is nullptr, then this is an async method
     76   MethodHandler* handler() const { return handler_.get(); }
     77   void SetHandler(MethodHandler* handler) { handler_.reset(handler); }
     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 
    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