diff options
author | Vijay Pai <vpai@google.com> | 2017-10-27 10:22:51 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-27 10:22:51 -0700 |
commit | 7a648854e9e53f5228ad1218b559e358f72a9a38 (patch) | |
tree | 1319f074426dc2787361d0ffd5c918f12ed24a79 /include/grpc++/impl | |
parent | 06e174a088edadae2081ee5843c70cd4ba017f78 (diff) |
Adopt the static factory pattern (#10)
* Switch sync streams from "struct internal" to static factory in namespace internal
* Reduce diff size
* fix friends
* Use static factory pattern for async unary calls
* Use static factories for async streams
* clang-format
Diffstat (limited to 'include/grpc++/impl')
-rw-r--r-- | include/grpc++/impl/codegen/async_stream.h | 147 | ||||
-rw-r--r-- | include/grpc++/impl/codegen/async_unary_call.h | 43 | ||||
-rw-r--r-- | include/grpc++/impl/codegen/channel_interface.h | 24 | ||||
-rw-r--r-- | include/grpc++/impl/codegen/sync_stream.h | 70 |
4 files changed, 160 insertions, 124 deletions
diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h index 2012b3170b..4476033463 100644 --- a/include/grpc++/impl/codegen/async_stream.h +++ b/include/grpc++/impl/codegen/async_stream.h @@ -159,33 +159,37 @@ class ClientAsyncReaderInterface : public internal::ClientAsyncStreamingInterface, public internal::AsyncReaderInterface<R> {}; +namespace internal { +template <class R> +class ClientAsyncReaderFactory { + public: + /// Create a stream object. + /// Write the first request out if \a start is set. + /// \a tag will be notified on \a cq when the call has been started and + /// \a request has been written out. If \a start is not set, \a tag must be + /// nullptr and the actual call must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + template <class W> + static ClientAsyncReader<R>* Create(ChannelInterface* channel, + CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ClientContext* context, const W& request, + bool start, void* tag) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + return new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncReader<R>))) + ClientAsyncReader<R>(call, context, request, start, tag); + } +}; +} // namespace internal + /// Async client-side API for doing server-streaming RPCs, /// where the incoming message stream coming from the server has /// messages of type \a R. template <class R> class ClientAsyncReader final : public ClientAsyncReaderInterface<R> { public: - struct internal { - /// Create a stream object. - /// Write the first request out if \a start is set. - /// \a tag will be notified on \a cq when the call has been started and - /// \a request has been written out. If \a start is not set, \a tag must be - /// nullptr and the actual call must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - template <class W> - static ClientAsyncReader* Create(ChannelInterface* channel, - CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ClientContext* context, const W& request, - bool start, void* tag) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncReader))) - ClientAsyncReader(call, context, request, start, tag); - } - }; - // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { assert(size == sizeof(ClientAsyncReader)); @@ -240,6 +244,7 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface<R> { } private: + friend class internal::ClientAsyncReaderFactory<R>; template <class W> ClientAsyncReader(::grpc::internal::Call call, ClientContext* context, const W& request, bool start, void* tag) @@ -291,37 +296,41 @@ class ClientAsyncWriterInterface virtual void WritesDone(void* tag) = 0; }; +namespace internal { +template <class W> +class ClientAsyncWriterFactory { + public: + /// Create a stream object. + /// Start the RPC if \a start is set + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent) and \a request has been written out. + /// If \a start is not set, \a tag must be nullptr and the actual call + /// must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + /// \a response will be filled in with the single expected response + /// message from the server upon a successful call to the \a Finish + /// method of this instance. + template <class R> + static ClientAsyncWriter<W>* Create(ChannelInterface* channel, + CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ClientContext* context, R* response, + bool start, void* tag) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + return new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncWriter<W>))) + ClientAsyncWriter<W>(call, context, response, start, tag); + } +}; +} // namespace internal + /// Async API on the client side for doing client-streaming RPCs, /// where the outgoing message stream going to the server contains /// messages of type \a W. template <class W> class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> { public: - struct internal { - /// Create a stream object. - /// Start the RPC if \a start is set - /// \a tag will be notified on \a cq when the call has been started (i.e. - /// intitial metadata sent) and \a request has been written out. - /// If \a start is not set, \a tag must be nullptr and the actual call - /// must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - /// \a response will be filled in with the single expected response - /// message from the server upon a successful call to the \a Finish - /// method of this instance. - template <class R> - static ClientAsyncWriter* Create(ChannelInterface* channel, - CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ClientContext* context, R* response, - bool start, void* tag) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncWriter))) - ClientAsyncWriter(call, context, response, start, tag); - } - }; - // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { assert(size == sizeof(ClientAsyncWriter)); @@ -394,6 +403,7 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> { } private: + friend class internal::ClientAsyncWriterFactory<W>; template <class R> ClientAsyncWriter(::grpc::internal::Call call, ClientContext* context, R* response, bool start, void* tag) @@ -449,6 +459,30 @@ class ClientAsyncReaderWriterInterface virtual void WritesDone(void* tag) = 0; }; +namespace internal { +template <class W, class R> +class ClientAsyncReaderWriterFactory { + public: + /// Create a stream object. + /// Start the RPC request if \a start is set. + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent). If \a start is not set, \a tag must be + /// nullptr and the actual call must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + static ClientAsyncReaderWriter<W, R>* Create( + ChannelInterface* channel, CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, ClientContext* context, + bool start, void* tag) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + + return new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncReaderWriter<W, R>))) + ClientAsyncReaderWriter<W, R>(call, context, start, tag); + } +}; +} // namespace internal + /// Async client-side interface for bi-directional streaming, /// where the outgoing message stream going to the server /// has messages of type \a W, and the incoming message stream coming @@ -457,26 +491,6 @@ template <class W, class R> class ClientAsyncReaderWriter final : public ClientAsyncReaderWriterInterface<W, R> { public: - struct internal { - /// Create a stream object. - /// Start the RPC request if \a start is set. - /// \a tag will be notified on \a cq when the call has been started (i.e. - /// intitial metadata sent). If \a start is not set, \a tag must be - /// nullptr and the actual call must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - static ClientAsyncReaderWriter* Create( - ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, ClientContext* context, - bool start, void* tag) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncReaderWriter))) - ClientAsyncReaderWriter(call, context, start, tag); - } - }; - // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { assert(size == sizeof(ClientAsyncReaderWriter)); @@ -556,6 +570,7 @@ class ClientAsyncReaderWriter final } private: + friend class internal::ClientAsyncReaderWriterFactory<W, R>; ClientAsyncReaderWriter(::grpc::internal::Call call, ClientContext* context, bool start, void* tag) : context_(context), call_(call), started_(start) { diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h index 8a3dfbc4db..6d51c78d5c 100644 --- a/include/grpc++/impl/codegen/async_unary_call.h +++ b/include/grpc++/impl/codegen/async_unary_call.h @@ -69,31 +69,35 @@ class ClientAsyncResponseReaderInterface { virtual void Finish(R* msg, Status* status, void* tag) = 0; }; +namespace internal { +template <class R> +class ClientAsyncResponseReaderFactory { + public: + /// Start a call and write the request out if \a start is set. + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent) and \a request has been written out. + /// If \a start is not set, the actual call must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + template <class W> + static ClientAsyncResponseReader<R>* Create( + ChannelInterface* channel, CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, ClientContext* context, + const W& request, bool start) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + return new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncResponseReader<R>))) + ClientAsyncResponseReader<R>(call, context, request, start); + } +}; +} // namespace internal + /// Async API for client-side unary RPCs, where the message response /// received from the server is of type \a R. template <class R> class ClientAsyncResponseReader final : public ClientAsyncResponseReaderInterface<R> { public: - struct internal { - /// Start a call and write the request out if \a start is set. - /// \a tag will be notified on \a cq when the call has been started (i.e. - /// intitial metadata sent) and \a request has been written out. - /// If \a start is not set, the actual call must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - template <class W> - static ClientAsyncResponseReader* Create( - ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, ClientContext* context, - const W& request, bool start) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncResponseReader))) - ClientAsyncResponseReader(call, context, request, start); - } - }; - // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { assert(size == sizeof(ClientAsyncResponseReader)); @@ -138,6 +142,7 @@ class ClientAsyncResponseReader final } private: + friend class internal::ClientAsyncResponseReaderFactory<R>; ClientContext* const context_; ::grpc::internal::Call call_; bool started_; diff --git a/include/grpc++/impl/codegen/channel_interface.h b/include/grpc++/impl/codegen/channel_interface.h index 41c213f64a..769f853974 100644 --- a/include/grpc++/impl/codegen/channel_interface.h +++ b/include/grpc++/impl/codegen/channel_interface.h @@ -34,14 +34,6 @@ template <class W> class ClientWriter; template <class W, class R> class ClientReaderWriter; -template <class R> -class ClientAsyncReader; -template <class W> -class ClientAsyncWriter; -template <class W, class R> -class ClientAsyncReaderWriter; -template <class R> -class ClientAsyncResponseReader; namespace internal { class Call; @@ -49,6 +41,14 @@ class CallOpSetInterface; class RpcMethod; template <class InputMessage, class OutputMessage> class BlockingUnaryCallImpl; +template <class R> +class ClientAsyncReaderFactory; +template <class W> +class ClientAsyncWriterFactory; +template <class W, class R> +class ClientAsyncReaderWriterFactory; +template <class R> +class ClientAsyncResponseReaderFactory; } // namespace internal /// Codegen interface for \a grpc::Channel. @@ -94,13 +94,13 @@ class ChannelInterface { template <class W, class R> friend class ::grpc::ClientReaderWriter; template <class R> - friend class ::grpc::ClientAsyncReader; + friend class ::grpc::internal::ClientAsyncReaderFactory; template <class W> - friend class ::grpc::ClientAsyncWriter; + friend class ::grpc::internal::ClientAsyncWriterFactory; template <class W, class R> - friend class ::grpc::ClientAsyncReaderWriter; + friend class ::grpc::internal::ClientAsyncReaderWriterFactory; template <class R> - friend class ::grpc::ClientAsyncResponseReader; + friend class ::grpc::internal::ClientAsyncResponseReaderFactory; template <class InputMessage, class OutputMessage> friend class ::grpc::internal::BlockingUnaryCallImpl; friend class ::grpc::internal::RpcMethod; diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h index 49ace0beeb..a6dd26fb00 100644 --- a/include/grpc++/impl/codegen/sync_stream.h +++ b/include/grpc++/impl/codegen/sync_stream.h @@ -156,21 +156,25 @@ class ClientReaderInterface : public internal::ClientStreamingInterface, virtual void WaitForInitialMetadata() = 0; }; +namespace internal { +template <class R> +class ClientReaderFactory { + public: + template <class W> + static ClientReader<R>* Create(ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ClientContext* context, const W& request) { + return new ClientReader<R>(channel, method, context, request); + } +}; +} // namespace internal + /// Synchronous (blocking) client-side API for doing server-streaming RPCs, /// where the stream of messages coming from the server has messages /// of type \a R. template <class R> class ClientReader final : public ClientReaderInterface<R> { public: - struct internal { - template <class W> - static ClientReader* Create(ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ClientContext* context, const W& request) { - return new ClientReader(channel, method, context, request); - } - }; - /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for /// semantics. /// @@ -225,6 +229,7 @@ class ClientReader final : public ClientReaderInterface<R> { } private: + friend class internal::ClientReaderFactory<R>; ClientContext* context_; CompletionQueue cq_; ::grpc::internal::Call call_; @@ -269,21 +274,25 @@ class ClientWriterInterface : public internal::ClientStreamingInterface, virtual bool WritesDone() = 0; }; +namespace internal { +template <class W> +class ClientWriterFactory { + public: + template <class R> + static ClientWriter<W>* Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ClientContext* context, R* response) { + return new ClientWriter<W>(channel, method, context, response); + } +}; +} // namespace internal + /// Synchronous (blocking) client-side API for doing client-streaming RPCs, /// where the outgoing message stream coming from the client has messages of /// type \a W. template <class W> class ClientWriter : public ClientWriterInterface<W> { public: - struct internal { - template <class R> - static ClientWriter* Create(::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ClientContext* context, R* response) { - return new ClientWriter(channel, method, context, response); - } - }; - /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for /// semantics. /// @@ -355,12 +364,13 @@ class ClientWriter : public ClientWriterInterface<W> { } private: + friend class internal::ClientWriterFactory<W>; + /// Block to create a stream (i.e. send request headers and other initial /// metadata to the server). Note that \a context will be used to fill /// in custom initial metadata. \a response will be filled in with the /// single expected response message from the server upon a successful /// call to the \a Finish method of this instance. - template <class R> ClientWriter(ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, @@ -415,6 +425,18 @@ class ClientReaderWriterInterface : public internal::ClientStreamingInterface, virtual bool WritesDone() = 0; }; +namespace internal { +template <class W, class R> +class ClientReaderWriterFactory { + public: + static ClientReaderWriter<W, R>* Create( + ::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, ClientContext* context) { + return new ClientReaderWriter<W, R>(channel, method, context); + } +}; +} // namespace internal + /// Synchronous (blocking) client-side API for bi-directional streaming RPCs, /// where the outgoing message stream coming from the client has messages of /// type \a W, and the incoming messages stream coming from the server has @@ -422,14 +444,6 @@ class ClientReaderWriterInterface : public internal::ClientStreamingInterface, template <class W, class R> class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> { public: - struct internal { - static ClientReaderWriter* Create(::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ClientContext* context) { - return new ClientReaderWriter(channel, method, context); - } - }; - /// Block waiting to read initial metadata from the server. /// This call is optional, but if it is used, it cannot be used concurrently /// with or after the \a Finish method. @@ -523,6 +537,8 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> { } private: + friend class internal::ClientReaderWriterFactory<W, R>; + ClientContext* context_; CompletionQueue cq_; ::grpc::internal::Call call_; |