aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/grpc++
diff options
context:
space:
mode:
authorGravatar Vijay Pai <vpai@google.com>2017-10-27 10:22:51 -0700
committerGravatar GitHub <noreply@github.com>2017-10-27 10:22:51 -0700
commit7a648854e9e53f5228ad1218b559e358f72a9a38 (patch)
tree1319f074426dc2787361d0ffd5c918f12ed24a79 /include/grpc++
parent06e174a088edadae2081ee5843c70cd4ba017f78 (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++')
-rw-r--r--include/grpc++/impl/codegen/async_stream.h147
-rw-r--r--include/grpc++/impl/codegen/async_unary_call.h43
-rw-r--r--include/grpc++/impl/codegen/channel_interface.h24
-rw-r--r--include/grpc++/impl/codegen/sync_stream.h70
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_;