xref: /aosp_15_r20/external/grpc-grpc/spm-cpp-include/grpcpp/server_interface.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2015 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker 
19*cc02d7e2SAndroid Build Coastguard Worker #ifndef GRPCPP_SERVER_INTERFACE_H
20*cc02d7e2SAndroid Build Coastguard Worker #define GRPCPP_SERVER_INTERFACE_H
21*cc02d7e2SAndroid Build Coastguard Worker 
22*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/grpc.h>
23*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/impl/grpc_types.h>
24*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/log.h>
25*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/port_platform.h>
26*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/time.h>
27*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/impl/call.h>
28*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/impl/call_hook.h>
29*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/impl/codegen/interceptor_common.h>
30*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/impl/completion_queue_tag.h>
31*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/impl/rpc_service_method.h>
32*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/server_context.h>
33*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/byte_buffer.h>
34*cc02d7e2SAndroid Build Coastguard Worker 
35*cc02d7e2SAndroid Build Coastguard Worker namespace grpc {
36*cc02d7e2SAndroid Build Coastguard Worker 
37*cc02d7e2SAndroid Build Coastguard Worker class AsyncGenericService;
38*cc02d7e2SAndroid Build Coastguard Worker class Channel;
39*cc02d7e2SAndroid Build Coastguard Worker class CompletionQueue;
40*cc02d7e2SAndroid Build Coastguard Worker class GenericServerContext;
41*cc02d7e2SAndroid Build Coastguard Worker class ServerCompletionQueue;
42*cc02d7e2SAndroid Build Coastguard Worker class ServerCredentials;
43*cc02d7e2SAndroid Build Coastguard Worker class Service;
44*cc02d7e2SAndroid Build Coastguard Worker 
45*cc02d7e2SAndroid Build Coastguard Worker /// Models a gRPC server.
46*cc02d7e2SAndroid Build Coastguard Worker ///
47*cc02d7e2SAndroid Build Coastguard Worker /// Servers are configured and started via \a grpc::ServerBuilder.
48*cc02d7e2SAndroid Build Coastguard Worker namespace internal {
49*cc02d7e2SAndroid Build Coastguard Worker class ServerAsyncStreamingInterface;
50*cc02d7e2SAndroid Build Coastguard Worker }  // namespace internal
51*cc02d7e2SAndroid Build Coastguard Worker 
52*cc02d7e2SAndroid Build Coastguard Worker class CallbackGenericService;
53*cc02d7e2SAndroid Build Coastguard Worker 
54*cc02d7e2SAndroid Build Coastguard Worker namespace experimental {
55*cc02d7e2SAndroid Build Coastguard Worker class ServerInterceptorFactoryInterface;
56*cc02d7e2SAndroid Build Coastguard Worker class ServerMetricRecorder;
57*cc02d7e2SAndroid Build Coastguard Worker }  // namespace experimental
58*cc02d7e2SAndroid Build Coastguard Worker 
59*cc02d7e2SAndroid Build Coastguard Worker class ServerInterface : public internal::CallHook {
60*cc02d7e2SAndroid Build Coastguard Worker  public:
~ServerInterface()61*cc02d7e2SAndroid Build Coastguard Worker   ~ServerInterface() override {}
62*cc02d7e2SAndroid Build Coastguard Worker 
63*cc02d7e2SAndroid Build Coastguard Worker   /// \a Shutdown does the following things:
64*cc02d7e2SAndroid Build Coastguard Worker   ///
65*cc02d7e2SAndroid Build Coastguard Worker   /// 1. Shutdown the server: deactivate all listening ports, mark it in
66*cc02d7e2SAndroid Build Coastguard Worker   ///    "shutdown mode" so that further call Request's or incoming RPC matches
67*cc02d7e2SAndroid Build Coastguard Worker   ///    are no longer allowed. Also return all Request'ed-but-not-yet-active
68*cc02d7e2SAndroid Build Coastguard Worker   ///    calls as failed (!ok). This refers to calls that have been requested
69*cc02d7e2SAndroid Build Coastguard Worker   ///    at the server by the server-side library or application code but that
70*cc02d7e2SAndroid Build Coastguard Worker   ///    have not yet been matched to incoming RPCs from the client. Note that
71*cc02d7e2SAndroid Build Coastguard Worker   ///    this would even include default calls added automatically by the gRPC
72*cc02d7e2SAndroid Build Coastguard Worker   ///    C++ API without the user's input (e.g., "Unimplemented RPC method")
73*cc02d7e2SAndroid Build Coastguard Worker   ///
74*cc02d7e2SAndroid Build Coastguard Worker   /// 2. Block until all rpc method handlers invoked automatically by the sync
75*cc02d7e2SAndroid Build Coastguard Worker   ///    API finish.
76*cc02d7e2SAndroid Build Coastguard Worker   ///
77*cc02d7e2SAndroid Build Coastguard Worker   /// 3. If all pending calls complete (and all their operations are
78*cc02d7e2SAndroid Build Coastguard Worker   ///    retrieved by Next) before \a deadline expires, this finishes
79*cc02d7e2SAndroid Build Coastguard Worker   ///    gracefully. Otherwise, forcefully cancel all pending calls associated
80*cc02d7e2SAndroid Build Coastguard Worker   ///    with the server after \a deadline expires. In the case of the sync API,
81*cc02d7e2SAndroid Build Coastguard Worker   ///    if the RPC function for a streaming call has already been started and
82*cc02d7e2SAndroid Build Coastguard Worker   ///    takes a week to complete, the RPC function won't be forcefully
83*cc02d7e2SAndroid Build Coastguard Worker   ///    terminated (since that would leave state corrupt and incomplete) and
84*cc02d7e2SAndroid Build Coastguard Worker   ///    the method handler will just keep running (which will prevent the
85*cc02d7e2SAndroid Build Coastguard Worker   ///    server from completing the "join" operation that it needs to do at
86*cc02d7e2SAndroid Build Coastguard Worker   ///    shutdown time).
87*cc02d7e2SAndroid Build Coastguard Worker   ///
88*cc02d7e2SAndroid Build Coastguard Worker   /// All completion queue associated with the server (for example, for async
89*cc02d7e2SAndroid Build Coastguard Worker   /// serving) must be shutdown *after* this method has returned:
90*cc02d7e2SAndroid Build Coastguard Worker   /// See \a ServerBuilder::AddCompletionQueue for details.
91*cc02d7e2SAndroid Build Coastguard Worker   /// They must also be drained (by repeated Next) after being shutdown.
92*cc02d7e2SAndroid Build Coastguard Worker   ///
93*cc02d7e2SAndroid Build Coastguard Worker   /// \param deadline How long to wait until pending rpcs are forcefully
94*cc02d7e2SAndroid Build Coastguard Worker   /// terminated.
95*cc02d7e2SAndroid Build Coastguard Worker   template <class T>
Shutdown(const T & deadline)96*cc02d7e2SAndroid Build Coastguard Worker   void Shutdown(const T& deadline) {
97*cc02d7e2SAndroid Build Coastguard Worker     ShutdownInternal(TimePoint<T>(deadline).raw_time());
98*cc02d7e2SAndroid Build Coastguard Worker   }
99*cc02d7e2SAndroid Build Coastguard Worker 
100*cc02d7e2SAndroid Build Coastguard Worker   /// Shutdown the server without a deadline and forced cancellation.
101*cc02d7e2SAndroid Build Coastguard Worker   ///
102*cc02d7e2SAndroid Build Coastguard Worker   /// All completion queue associated with the server (for example, for async
103*cc02d7e2SAndroid Build Coastguard Worker   /// serving) must be shutdown *after* this method has returned:
104*cc02d7e2SAndroid Build Coastguard Worker   /// See \a ServerBuilder::AddCompletionQueue for details.
Shutdown()105*cc02d7e2SAndroid Build Coastguard Worker   void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
106*cc02d7e2SAndroid Build Coastguard Worker 
107*cc02d7e2SAndroid Build Coastguard Worker   /// Block waiting for all work to complete.
108*cc02d7e2SAndroid Build Coastguard Worker   ///
109*cc02d7e2SAndroid Build Coastguard Worker   /// \warning The server must be either shutting down or some other thread must
110*cc02d7e2SAndroid Build Coastguard Worker   /// call \a Shutdown for this function to ever return.
111*cc02d7e2SAndroid Build Coastguard Worker   virtual void Wait() = 0;
112*cc02d7e2SAndroid Build Coastguard Worker 
113*cc02d7e2SAndroid Build Coastguard Worker  protected:
114*cc02d7e2SAndroid Build Coastguard Worker   friend class grpc::Service;
115*cc02d7e2SAndroid Build Coastguard Worker 
116*cc02d7e2SAndroid Build Coastguard Worker   /// Register a service. This call does not take ownership of the service.
117*cc02d7e2SAndroid Build Coastguard Worker   /// The service must exist for the lifetime of the Server instance.
118*cc02d7e2SAndroid Build Coastguard Worker   virtual bool RegisterService(const std::string* host, Service* service) = 0;
119*cc02d7e2SAndroid Build Coastguard Worker 
120*cc02d7e2SAndroid Build Coastguard Worker   /// Register a generic service. This call does not take ownership of the
121*cc02d7e2SAndroid Build Coastguard Worker   /// service. The service must exist for the lifetime of the Server instance.
122*cc02d7e2SAndroid Build Coastguard Worker   virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0;
123*cc02d7e2SAndroid Build Coastguard Worker 
124*cc02d7e2SAndroid Build Coastguard Worker   /// Register a callback generic service. This call does not take ownership of
125*cc02d7e2SAndroid Build Coastguard Worker   /// the  service. The service must exist for the lifetime of the Server
126*cc02d7e2SAndroid Build Coastguard Worker   /// instance. May not be abstract since this is a post-1.0 API addition.
127*cc02d7e2SAndroid Build Coastguard Worker 
RegisterCallbackGenericService(CallbackGenericService *)128*cc02d7e2SAndroid Build Coastguard Worker   virtual void RegisterCallbackGenericService(CallbackGenericService*
129*cc02d7e2SAndroid Build Coastguard Worker                                               /*service*/) {}
130*cc02d7e2SAndroid Build Coastguard Worker 
131*cc02d7e2SAndroid Build Coastguard Worker   /// Tries to bind \a server to the given \a addr.
132*cc02d7e2SAndroid Build Coastguard Worker   ///
133*cc02d7e2SAndroid Build Coastguard Worker   /// It can be invoked multiple times.
134*cc02d7e2SAndroid Build Coastguard Worker   ///
135*cc02d7e2SAndroid Build Coastguard Worker   /// \param addr The address to try to bind to the server (eg, localhost:1234,
136*cc02d7e2SAndroid Build Coastguard Worker   /// 192.168.1.1:31416, [::1]:27182, etc.).
137*cc02d7e2SAndroid Build Coastguard Worker   /// \params creds The credentials associated with the server.
138*cc02d7e2SAndroid Build Coastguard Worker   ///
139*cc02d7e2SAndroid Build Coastguard Worker   /// \return bound port number on success, 0 on failure.
140*cc02d7e2SAndroid Build Coastguard Worker   ///
141*cc02d7e2SAndroid Build Coastguard Worker   /// \warning It's an error to call this method on an already started server.
142*cc02d7e2SAndroid Build Coastguard Worker   virtual int AddListeningPort(const std::string& addr,
143*cc02d7e2SAndroid Build Coastguard Worker                                ServerCredentials* creds) = 0;
144*cc02d7e2SAndroid Build Coastguard Worker 
145*cc02d7e2SAndroid Build Coastguard Worker   /// Start the server.
146*cc02d7e2SAndroid Build Coastguard Worker   ///
147*cc02d7e2SAndroid Build Coastguard Worker   /// \param cqs Completion queues for handling asynchronous services. The
148*cc02d7e2SAndroid Build Coastguard Worker   /// caller is required to keep all completion queues live until the server is
149*cc02d7e2SAndroid Build Coastguard Worker   /// destroyed.
150*cc02d7e2SAndroid Build Coastguard Worker   /// \param num_cqs How many completion queues does \a cqs hold.
151*cc02d7e2SAndroid Build Coastguard Worker   virtual void Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) = 0;
152*cc02d7e2SAndroid Build Coastguard Worker 
153*cc02d7e2SAndroid Build Coastguard Worker   virtual void ShutdownInternal(gpr_timespec deadline) = 0;
154*cc02d7e2SAndroid Build Coastguard Worker 
155*cc02d7e2SAndroid Build Coastguard Worker   virtual int max_receive_message_size() const = 0;
156*cc02d7e2SAndroid Build Coastguard Worker 
157*cc02d7e2SAndroid Build Coastguard Worker   virtual grpc_server* server() = 0;
158*cc02d7e2SAndroid Build Coastguard Worker 
159*cc02d7e2SAndroid Build Coastguard Worker   void PerformOpsOnCall(internal::CallOpSetInterface* ops,
160*cc02d7e2SAndroid Build Coastguard Worker                         internal::Call* call) override = 0;
161*cc02d7e2SAndroid Build Coastguard Worker 
162*cc02d7e2SAndroid Build Coastguard Worker   class BaseAsyncRequest : public internal::CompletionQueueTag {
163*cc02d7e2SAndroid Build Coastguard Worker    public:
164*cc02d7e2SAndroid Build Coastguard Worker     BaseAsyncRequest(ServerInterface* server, grpc::ServerContext* context,
165*cc02d7e2SAndroid Build Coastguard Worker                      internal::ServerAsyncStreamingInterface* stream,
166*cc02d7e2SAndroid Build Coastguard Worker                      grpc::CompletionQueue* call_cq,
167*cc02d7e2SAndroid Build Coastguard Worker                      grpc::ServerCompletionQueue* notification_cq, void* tag,
168*cc02d7e2SAndroid Build Coastguard Worker                      bool delete_on_finalize);
169*cc02d7e2SAndroid Build Coastguard Worker     ~BaseAsyncRequest() override;
170*cc02d7e2SAndroid Build Coastguard Worker 
171*cc02d7e2SAndroid Build Coastguard Worker     bool FinalizeResult(void** tag, bool* status) override;
172*cc02d7e2SAndroid Build Coastguard Worker 
173*cc02d7e2SAndroid Build Coastguard Worker    private:
174*cc02d7e2SAndroid Build Coastguard Worker     void ContinueFinalizeResultAfterInterception();
175*cc02d7e2SAndroid Build Coastguard Worker 
176*cc02d7e2SAndroid Build Coastguard Worker    protected:
177*cc02d7e2SAndroid Build Coastguard Worker     ServerInterface* const server_;
178*cc02d7e2SAndroid Build Coastguard Worker     grpc::ServerContext* const context_;
179*cc02d7e2SAndroid Build Coastguard Worker     internal::ServerAsyncStreamingInterface* const stream_;
180*cc02d7e2SAndroid Build Coastguard Worker     grpc::CompletionQueue* const call_cq_;
181*cc02d7e2SAndroid Build Coastguard Worker     grpc::ServerCompletionQueue* const notification_cq_;
182*cc02d7e2SAndroid Build Coastguard Worker     void* const tag_;
183*cc02d7e2SAndroid Build Coastguard Worker     const bool delete_on_finalize_;
184*cc02d7e2SAndroid Build Coastguard Worker     grpc_call* call_;
185*cc02d7e2SAndroid Build Coastguard Worker     internal::Call call_wrapper_;
186*cc02d7e2SAndroid Build Coastguard Worker     internal::InterceptorBatchMethodsImpl interceptor_methods_;
187*cc02d7e2SAndroid Build Coastguard Worker     bool done_intercepting_;
188*cc02d7e2SAndroid Build Coastguard Worker     bool call_metric_recording_enabled_;
189*cc02d7e2SAndroid Build Coastguard Worker     experimental::ServerMetricRecorder* server_metric_recorder_;
190*cc02d7e2SAndroid Build Coastguard Worker   };
191*cc02d7e2SAndroid Build Coastguard Worker 
192*cc02d7e2SAndroid Build Coastguard Worker   /// RegisteredAsyncRequest is not part of the C++ API
193*cc02d7e2SAndroid Build Coastguard Worker   class RegisteredAsyncRequest : public BaseAsyncRequest {
194*cc02d7e2SAndroid Build Coastguard Worker    public:
195*cc02d7e2SAndroid Build Coastguard Worker     RegisteredAsyncRequest(ServerInterface* server,
196*cc02d7e2SAndroid Build Coastguard Worker                            grpc::ServerContext* context,
197*cc02d7e2SAndroid Build Coastguard Worker                            internal::ServerAsyncStreamingInterface* stream,
198*cc02d7e2SAndroid Build Coastguard Worker                            grpc::CompletionQueue* call_cq,
199*cc02d7e2SAndroid Build Coastguard Worker                            grpc::ServerCompletionQueue* notification_cq,
200*cc02d7e2SAndroid Build Coastguard Worker                            void* tag, const char* name,
201*cc02d7e2SAndroid Build Coastguard Worker                            internal::RpcMethod::RpcType type);
202*cc02d7e2SAndroid Build Coastguard Worker 
FinalizeResult(void ** tag,bool * status)203*cc02d7e2SAndroid Build Coastguard Worker     bool FinalizeResult(void** tag, bool* status) override {
204*cc02d7e2SAndroid Build Coastguard Worker       // If we are done intercepting, then there is nothing more for us to do
205*cc02d7e2SAndroid Build Coastguard Worker       if (done_intercepting_) {
206*cc02d7e2SAndroid Build Coastguard Worker         return BaseAsyncRequest::FinalizeResult(tag, status);
207*cc02d7e2SAndroid Build Coastguard Worker       }
208*cc02d7e2SAndroid Build Coastguard Worker       call_wrapper_ = grpc::internal::Call(
209*cc02d7e2SAndroid Build Coastguard Worker           call_, server_, call_cq_, server_->max_receive_message_size(),
210*cc02d7e2SAndroid Build Coastguard Worker           context_->set_server_rpc_info(name_, type_,
211*cc02d7e2SAndroid Build Coastguard Worker                                         *server_->interceptor_creators()));
212*cc02d7e2SAndroid Build Coastguard Worker       return BaseAsyncRequest::FinalizeResult(tag, status);
213*cc02d7e2SAndroid Build Coastguard Worker     }
214*cc02d7e2SAndroid Build Coastguard Worker 
215*cc02d7e2SAndroid Build Coastguard Worker    protected:
216*cc02d7e2SAndroid Build Coastguard Worker     void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
217*cc02d7e2SAndroid Build Coastguard Worker                       grpc::ServerCompletionQueue* notification_cq);
218*cc02d7e2SAndroid Build Coastguard Worker     const char* name_;
219*cc02d7e2SAndroid Build Coastguard Worker     const internal::RpcMethod::RpcType type_;
220*cc02d7e2SAndroid Build Coastguard Worker   };
221*cc02d7e2SAndroid Build Coastguard Worker 
222*cc02d7e2SAndroid Build Coastguard Worker   class NoPayloadAsyncRequest final : public RegisteredAsyncRequest {
223*cc02d7e2SAndroid Build Coastguard Worker    public:
NoPayloadAsyncRequest(internal::RpcServiceMethod * registered_method,ServerInterface * server,grpc::ServerContext * context,internal::ServerAsyncStreamingInterface * stream,grpc::CompletionQueue * call_cq,grpc::ServerCompletionQueue * notification_cq,void * tag)224*cc02d7e2SAndroid Build Coastguard Worker     NoPayloadAsyncRequest(internal::RpcServiceMethod* registered_method,
225*cc02d7e2SAndroid Build Coastguard Worker                           ServerInterface* server, grpc::ServerContext* context,
226*cc02d7e2SAndroid Build Coastguard Worker                           internal::ServerAsyncStreamingInterface* stream,
227*cc02d7e2SAndroid Build Coastguard Worker                           grpc::CompletionQueue* call_cq,
228*cc02d7e2SAndroid Build Coastguard Worker                           grpc::ServerCompletionQueue* notification_cq,
229*cc02d7e2SAndroid Build Coastguard Worker                           void* tag)
230*cc02d7e2SAndroid Build Coastguard Worker         : RegisteredAsyncRequest(
231*cc02d7e2SAndroid Build Coastguard Worker               server, context, stream, call_cq, notification_cq, tag,
232*cc02d7e2SAndroid Build Coastguard Worker               registered_method->name(), registered_method->method_type()) {
233*cc02d7e2SAndroid Build Coastguard Worker       IssueRequest(registered_method->server_tag(), nullptr, notification_cq);
234*cc02d7e2SAndroid Build Coastguard Worker     }
235*cc02d7e2SAndroid Build Coastguard Worker 
236*cc02d7e2SAndroid Build Coastguard Worker     // uses RegisteredAsyncRequest::FinalizeResult
237*cc02d7e2SAndroid Build Coastguard Worker   };
238*cc02d7e2SAndroid Build Coastguard Worker 
239*cc02d7e2SAndroid Build Coastguard Worker   template <class Message>
240*cc02d7e2SAndroid Build Coastguard Worker   class PayloadAsyncRequest final : public RegisteredAsyncRequest {
241*cc02d7e2SAndroid Build Coastguard Worker    public:
PayloadAsyncRequest(internal::RpcServiceMethod * registered_method,ServerInterface * server,grpc::ServerContext * context,internal::ServerAsyncStreamingInterface * stream,grpc::CompletionQueue * call_cq,grpc::ServerCompletionQueue * notification_cq,void * tag,Message * request)242*cc02d7e2SAndroid Build Coastguard Worker     PayloadAsyncRequest(internal::RpcServiceMethod* registered_method,
243*cc02d7e2SAndroid Build Coastguard Worker                         ServerInterface* server, grpc::ServerContext* context,
244*cc02d7e2SAndroid Build Coastguard Worker                         internal::ServerAsyncStreamingInterface* stream,
245*cc02d7e2SAndroid Build Coastguard Worker                         grpc::CompletionQueue* call_cq,
246*cc02d7e2SAndroid Build Coastguard Worker                         grpc::ServerCompletionQueue* notification_cq, void* tag,
247*cc02d7e2SAndroid Build Coastguard Worker                         Message* request)
248*cc02d7e2SAndroid Build Coastguard Worker         : RegisteredAsyncRequest(
249*cc02d7e2SAndroid Build Coastguard Worker               server, context, stream, call_cq, notification_cq, tag,
250*cc02d7e2SAndroid Build Coastguard Worker               registered_method->name(), registered_method->method_type()),
251*cc02d7e2SAndroid Build Coastguard Worker           registered_method_(registered_method),
252*cc02d7e2SAndroid Build Coastguard Worker           request_(request) {
253*cc02d7e2SAndroid Build Coastguard Worker       IssueRequest(registered_method->server_tag(), payload_.bbuf_ptr(),
254*cc02d7e2SAndroid Build Coastguard Worker                    notification_cq);
255*cc02d7e2SAndroid Build Coastguard Worker     }
256*cc02d7e2SAndroid Build Coastguard Worker 
~PayloadAsyncRequest()257*cc02d7e2SAndroid Build Coastguard Worker     ~PayloadAsyncRequest() override {
258*cc02d7e2SAndroid Build Coastguard Worker       payload_.Release();  // We do not own the payload_
259*cc02d7e2SAndroid Build Coastguard Worker     }
260*cc02d7e2SAndroid Build Coastguard Worker 
FinalizeResult(void ** tag,bool * status)261*cc02d7e2SAndroid Build Coastguard Worker     bool FinalizeResult(void** tag, bool* status) override {
262*cc02d7e2SAndroid Build Coastguard Worker       // If we are done intercepting, then there is nothing more for us to do
263*cc02d7e2SAndroid Build Coastguard Worker       if (done_intercepting_) {
264*cc02d7e2SAndroid Build Coastguard Worker         return RegisteredAsyncRequest::FinalizeResult(tag, status);
265*cc02d7e2SAndroid Build Coastguard Worker       }
266*cc02d7e2SAndroid Build Coastguard Worker       if (*status) {
267*cc02d7e2SAndroid Build Coastguard Worker         if (!payload_.Valid() || !SerializationTraits<Message>::Deserialize(
268*cc02d7e2SAndroid Build Coastguard Worker                                       payload_.bbuf_ptr(), request_)
269*cc02d7e2SAndroid Build Coastguard Worker                                       .ok()) {
270*cc02d7e2SAndroid Build Coastguard Worker           // If deserialization fails, we cancel the call and instantiate
271*cc02d7e2SAndroid Build Coastguard Worker           // a new instance of ourselves to request another call.  We then
272*cc02d7e2SAndroid Build Coastguard Worker           // return false, which prevents the call from being returned to
273*cc02d7e2SAndroid Build Coastguard Worker           // the application.
274*cc02d7e2SAndroid Build Coastguard Worker           grpc_call_cancel_with_status(call_, GRPC_STATUS_INTERNAL,
275*cc02d7e2SAndroid Build Coastguard Worker                                        "Unable to parse request", nullptr);
276*cc02d7e2SAndroid Build Coastguard Worker           grpc_call_unref(call_);
277*cc02d7e2SAndroid Build Coastguard Worker           new PayloadAsyncRequest(registered_method_, server_, context_,
278*cc02d7e2SAndroid Build Coastguard Worker                                   stream_, call_cq_, notification_cq_, tag_,
279*cc02d7e2SAndroid Build Coastguard Worker                                   request_);
280*cc02d7e2SAndroid Build Coastguard Worker           delete this;
281*cc02d7e2SAndroid Build Coastguard Worker           return false;
282*cc02d7e2SAndroid Build Coastguard Worker         }
283*cc02d7e2SAndroid Build Coastguard Worker       }
284*cc02d7e2SAndroid Build Coastguard Worker       // Set interception point for recv message
285*cc02d7e2SAndroid Build Coastguard Worker       interceptor_methods_.AddInterceptionHookPoint(
286*cc02d7e2SAndroid Build Coastguard Worker           experimental::InterceptionHookPoints::POST_RECV_MESSAGE);
287*cc02d7e2SAndroid Build Coastguard Worker       interceptor_methods_.SetRecvMessage(request_, nullptr);
288*cc02d7e2SAndroid Build Coastguard Worker       return RegisteredAsyncRequest::FinalizeResult(tag, status);
289*cc02d7e2SAndroid Build Coastguard Worker     }
290*cc02d7e2SAndroid Build Coastguard Worker 
291*cc02d7e2SAndroid Build Coastguard Worker    private:
292*cc02d7e2SAndroid Build Coastguard Worker     internal::RpcServiceMethod* const registered_method_;
293*cc02d7e2SAndroid Build Coastguard Worker     Message* const request_;
294*cc02d7e2SAndroid Build Coastguard Worker     ByteBuffer payload_;
295*cc02d7e2SAndroid Build Coastguard Worker   };
296*cc02d7e2SAndroid Build Coastguard Worker 
297*cc02d7e2SAndroid Build Coastguard Worker   class GenericAsyncRequest : public BaseAsyncRequest {
298*cc02d7e2SAndroid Build Coastguard Worker    public:
299*cc02d7e2SAndroid Build Coastguard Worker     GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
300*cc02d7e2SAndroid Build Coastguard Worker                         internal::ServerAsyncStreamingInterface* stream,
301*cc02d7e2SAndroid Build Coastguard Worker                         grpc::CompletionQueue* call_cq,
302*cc02d7e2SAndroid Build Coastguard Worker                         grpc::ServerCompletionQueue* notification_cq, void* tag,
303*cc02d7e2SAndroid Build Coastguard Worker                         bool delete_on_finalize, bool issue_request = true);
304*cc02d7e2SAndroid Build Coastguard Worker 
305*cc02d7e2SAndroid Build Coastguard Worker     bool FinalizeResult(void** tag, bool* status) override;
306*cc02d7e2SAndroid Build Coastguard Worker 
307*cc02d7e2SAndroid Build Coastguard Worker    protected:
308*cc02d7e2SAndroid Build Coastguard Worker     void IssueRequest();
309*cc02d7e2SAndroid Build Coastguard Worker 
310*cc02d7e2SAndroid Build Coastguard Worker    private:
311*cc02d7e2SAndroid Build Coastguard Worker     grpc_call_details call_details_;
312*cc02d7e2SAndroid Build Coastguard Worker   };
313*cc02d7e2SAndroid Build Coastguard Worker 
314*cc02d7e2SAndroid Build Coastguard Worker   template <class Message>
RequestAsyncCall(internal::RpcServiceMethod * method,grpc::ServerContext * context,internal::ServerAsyncStreamingInterface * stream,grpc::CompletionQueue * call_cq,grpc::ServerCompletionQueue * notification_cq,void * tag,Message * message)315*cc02d7e2SAndroid Build Coastguard Worker   void RequestAsyncCall(internal::RpcServiceMethod* method,
316*cc02d7e2SAndroid Build Coastguard Worker                         grpc::ServerContext* context,
317*cc02d7e2SAndroid Build Coastguard Worker                         internal::ServerAsyncStreamingInterface* stream,
318*cc02d7e2SAndroid Build Coastguard Worker                         grpc::CompletionQueue* call_cq,
319*cc02d7e2SAndroid Build Coastguard Worker                         grpc::ServerCompletionQueue* notification_cq, void* tag,
320*cc02d7e2SAndroid Build Coastguard Worker                         Message* message) {
321*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(method);
322*cc02d7e2SAndroid Build Coastguard Worker     new PayloadAsyncRequest<Message>(method, this, context, stream, call_cq,
323*cc02d7e2SAndroid Build Coastguard Worker                                      notification_cq, tag, message);
324*cc02d7e2SAndroid Build Coastguard Worker   }
325*cc02d7e2SAndroid Build Coastguard Worker 
RequestAsyncCall(internal::RpcServiceMethod * method,grpc::ServerContext * context,internal::ServerAsyncStreamingInterface * stream,grpc::CompletionQueue * call_cq,grpc::ServerCompletionQueue * notification_cq,void * tag)326*cc02d7e2SAndroid Build Coastguard Worker   void RequestAsyncCall(internal::RpcServiceMethod* method,
327*cc02d7e2SAndroid Build Coastguard Worker                         grpc::ServerContext* context,
328*cc02d7e2SAndroid Build Coastguard Worker                         internal::ServerAsyncStreamingInterface* stream,
329*cc02d7e2SAndroid Build Coastguard Worker                         grpc::CompletionQueue* call_cq,
330*cc02d7e2SAndroid Build Coastguard Worker                         grpc::ServerCompletionQueue* notification_cq,
331*cc02d7e2SAndroid Build Coastguard Worker                         void* tag) {
332*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(method);
333*cc02d7e2SAndroid Build Coastguard Worker     new NoPayloadAsyncRequest(method, this, context, stream, call_cq,
334*cc02d7e2SAndroid Build Coastguard Worker                               notification_cq, tag);
335*cc02d7e2SAndroid Build Coastguard Worker   }
336*cc02d7e2SAndroid Build Coastguard Worker 
RequestAsyncGenericCall(GenericServerContext * context,internal::ServerAsyncStreamingInterface * stream,grpc::CompletionQueue * call_cq,grpc::ServerCompletionQueue * notification_cq,void * tag)337*cc02d7e2SAndroid Build Coastguard Worker   void RequestAsyncGenericCall(GenericServerContext* context,
338*cc02d7e2SAndroid Build Coastguard Worker                                internal::ServerAsyncStreamingInterface* stream,
339*cc02d7e2SAndroid Build Coastguard Worker                                grpc::CompletionQueue* call_cq,
340*cc02d7e2SAndroid Build Coastguard Worker                                grpc::ServerCompletionQueue* notification_cq,
341*cc02d7e2SAndroid Build Coastguard Worker                                void* tag) {
342*cc02d7e2SAndroid Build Coastguard Worker     new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
343*cc02d7e2SAndroid Build Coastguard Worker                             tag, true);
344*cc02d7e2SAndroid Build Coastguard Worker   }
345*cc02d7e2SAndroid Build Coastguard Worker 
346*cc02d7e2SAndroid Build Coastguard Worker  private:
347*cc02d7e2SAndroid Build Coastguard Worker   // EXPERIMENTAL
348*cc02d7e2SAndroid Build Coastguard Worker   // Getter method for the vector of interceptor factory objects.
349*cc02d7e2SAndroid Build Coastguard Worker   // Returns a nullptr (rather than being pure) since this is a post-1.0 method
350*cc02d7e2SAndroid Build Coastguard Worker   // and adding a new pure method to an interface would be a breaking change
351*cc02d7e2SAndroid Build Coastguard Worker   // (even though this is private and non-API)
352*cc02d7e2SAndroid Build Coastguard Worker   virtual std::vector<
353*cc02d7e2SAndroid Build Coastguard Worker       std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>*
interceptor_creators()354*cc02d7e2SAndroid Build Coastguard Worker   interceptor_creators() {
355*cc02d7e2SAndroid Build Coastguard Worker     return nullptr;
356*cc02d7e2SAndroid Build Coastguard Worker   }
357*cc02d7e2SAndroid Build Coastguard Worker 
358*cc02d7e2SAndroid Build Coastguard Worker   // Whether per-call load reporting is enabled.
359*cc02d7e2SAndroid Build Coastguard Worker   virtual bool call_metric_recording_enabled() const = 0;
360*cc02d7e2SAndroid Build Coastguard Worker 
361*cc02d7e2SAndroid Build Coastguard Worker   // Interface to read or update server-wide metrics. Returns null when not set.
362*cc02d7e2SAndroid Build Coastguard Worker   virtual experimental::ServerMetricRecorder* server_metric_recorder()
363*cc02d7e2SAndroid Build Coastguard Worker       const = 0;
364*cc02d7e2SAndroid Build Coastguard Worker 
365*cc02d7e2SAndroid Build Coastguard Worker   // A method to get the callbackable completion queue associated with this
366*cc02d7e2SAndroid Build Coastguard Worker   // server. If the return value is nullptr, this server doesn't support
367*cc02d7e2SAndroid Build Coastguard Worker   // callback operations.
368*cc02d7e2SAndroid Build Coastguard Worker   // TODO(vjpai): Consider a better default like using a global CQ
369*cc02d7e2SAndroid Build Coastguard Worker   // Returns nullptr (rather than being pure) since this is a post-1.0 method
370*cc02d7e2SAndroid Build Coastguard Worker   // and adding a new pure method to an interface would be a breaking change
371*cc02d7e2SAndroid Build Coastguard Worker   // (even though this is private and non-API)
CallbackCQ()372*cc02d7e2SAndroid Build Coastguard Worker   virtual grpc::CompletionQueue* CallbackCQ() { return nullptr; }
373*cc02d7e2SAndroid Build Coastguard Worker };
374*cc02d7e2SAndroid Build Coastguard Worker 
375*cc02d7e2SAndroid Build Coastguard Worker }  // namespace grpc
376*cc02d7e2SAndroid Build Coastguard Worker 
377*cc02d7e2SAndroid Build Coastguard Worker #endif  // GRPCPP_SERVER_INTERFACE_H
378