// // // Copyright 2018 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_SUPPORT_CLIENT_CALLBACK_H #define GRPCPP_SUPPORT_CLIENT_CALLBACK_H #include <atomic> #include <functional> #include <grpc/grpc.h> #include <grpc/support/log.h> #include <grpcpp/impl/call.h> #include <grpcpp/impl/call_op_set.h> #include <grpcpp/impl/sync.h> #include <grpcpp/support/callback_common.h> #include <grpcpp/support/config.h> #include <grpcpp/support/status.h> namespace grpc { class Channel; class ClientContext; namespace internal { class RpcMethod; /// Perform a callback-based unary call. May optionally specify the base /// class of the Request and Response so that the internal calls and structures /// below this may be based on those base classes and thus achieve code reuse /// across different RPCs (e.g., for protobuf, MessageLite would be a base /// class). /// TODO(vjpai): Combine as much as possible with the blocking unary call code template <class InputMessage, class OutputMessage, class BaseInputMessage = InputMessage, class BaseOutputMessage = OutputMessage> void CallbackUnaryCall(grpc::ChannelInterface* channel, const grpc::internal::RpcMethod& method, grpc::ClientContext* context, const InputMessage* request, OutputMessage* result, std::function<void(grpc::Status)> on_completion) { … } template <class InputMessage, class OutputMessage> class CallbackUnaryCallImpl { … }; // Base class for public API classes. class ClientReactor { … }; } // namespace internal // Forward declarations template <class Request, class Response> class ClientBidiReactor; template <class Response> class ClientReadReactor; template <class Request> class ClientWriteReactor; class ClientUnaryReactor; // NOTE: The streaming objects are not actually implemented in the public API. // These interfaces are provided for mocking only. Typical applications // will interact exclusively with the reactors that they define. template <class Request, class Response> class ClientCallbackReaderWriter { … }; template <class Response> class ClientCallbackReader { … }; template <class Request> class ClientCallbackWriter { … }; class ClientCallbackUnary { … }; // The following classes are the reactor interfaces that are to be implemented // by the user. They are passed in to the library as an argument to a call on a // stub (either a codegen-ed call or a generic call). The streaming RPC is // activated by calling StartCall, possibly after initiating StartRead, // StartWrite, or AddHold operations on the streaming object. Note that none of // the classes are pure; all reactions have a default empty reaction so that the // user class only needs to override those reactions that it cares about. // The reactor must be passed to the stub invocation before any of the below // operations can be called and its reactions will be invoked by the library in // response to the completion of various operations. Reactions must not include // blocking operations (such as blocking I/O, starting synchronous RPCs, or // waiting on condition variables). Reactions may be invoked concurrently, // except that OnDone is called after all others (assuming proper API usage). // The reactor may not be deleted until OnDone is called. /// \a ClientBidiReactor is the interface for a bidirectional streaming RPC. template <class Request, class Response> class ClientBidiReactor : public internal::ClientReactor { … }; /// \a ClientReadReactor is the interface for a server-streaming RPC. /// All public methods behave as in ClientBidiReactor. template <class Response> class ClientReadReactor : public internal::ClientReactor { … }; /// \a ClientWriteReactor is the interface for a client-streaming RPC. /// All public methods behave as in ClientBidiReactor. template <class Request> class ClientWriteReactor : public internal::ClientReactor { … }; /// \a ClientUnaryReactor is a reactor-style interface for a unary RPC. /// This is _not_ a common way of invoking a unary RPC. In practice, this /// option should be used only if the unary RPC wants to receive initial /// metadata without waiting for the response to complete. Most deployments of /// RPC systems do not use this option, but it is needed for generality. /// All public methods behave as in ClientBidiReactor. /// StartCall is included for consistency with the other reactor flavors: even /// though there are no StartRead or StartWrite operations to queue before the /// call (that is part of the unary call itself) and there is no reactor object /// being created as a result of this call, we keep a consistent 2-phase /// initiation API among all the reactor flavors. class ClientUnaryReactor : public internal::ClientReactor { … }; // Define function out-of-line from class to avoid forward declaration issue inline void ClientCallbackUnary::BindReactor(ClientUnaryReactor* reactor) { … } namespace internal { // Forward declare factory classes for friendship template <class Request, class Response> class ClientCallbackReaderWriterFactory; template <class Response> class ClientCallbackReaderFactory; template <class Request> class ClientCallbackWriterFactory; template <class Request, class Response> class ClientCallbackReaderWriterImpl : public ClientCallbackReaderWriter<Request, Response> { … }; template <class Request, class Response> class ClientCallbackReaderWriterFactory { … }; template <class Response> class ClientCallbackReaderImpl : public ClientCallbackReader<Response> { … }; template <class Response> class ClientCallbackReaderFactory { … }; template <class Request> class ClientCallbackWriterImpl : public ClientCallbackWriter<Request> { … }; template <class Request> class ClientCallbackWriterFactory { … }; class ClientCallbackUnaryImpl final : public ClientCallbackUnary { … }; class ClientCallbackUnaryFactory { … }; } // namespace internal } // namespace grpc #endif // GRPCPP_SUPPORT_CLIENT_CALLBACK_H