aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/grpc++/impl/codegen/completion_queue.h8
-rw-r--r--include/grpc++/impl/codegen/method_handler_impl.h19
-rw-r--r--include/grpc++/impl/codegen/server_context.h8
-rw-r--r--src/compiler/cpp_generator.cc8
-rw-r--r--test/cpp/end2end/hybrid_end2end_test.cc39
5 files changed, 68 insertions, 14 deletions
diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h
index 1b84b44705..2286f01b8a 100644
--- a/include/grpc++/impl/codegen/completion_queue.h
+++ b/include/grpc++/impl/codegen/completion_queue.h
@@ -59,6 +59,8 @@ template <class W>
class ServerWriter;
template <class W, class R>
class ServerReaderWriter;
+template <class Req, class Resp>
+class FCUnary;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@@ -67,6 +69,8 @@ template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class FCUnaryMethodHandler;
class UnknownMethodHandler;
class Channel;
@@ -168,6 +172,8 @@ class CompletionQueue : private GrpcLibraryCodegen {
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::ServerReaderWriter;
+ template <class Req, class Resp>
+ friend class ::grpc::FCUnary;
template <class ServiceType, class RequestType, class ResponseType>
friend class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@@ -176,6 +182,8 @@ class CompletionQueue : private GrpcLibraryCodegen {
friend class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class BidiStreamingHandler;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class FCUnaryMethodHandler;
friend class UnknownMethodHandler;
friend class ::grpc::Server;
friend class ::grpc::ServerContext;
diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h
index 2a14ef3977..293ae6a4d8 100644
--- a/include/grpc++/impl/codegen/method_handler_impl.h
+++ b/include/grpc++/impl/codegen/method_handler_impl.h
@@ -193,19 +193,22 @@ class BidiStreamingHandler : public MethodHandler {
// A wrapper class of an application provided rpc method handler
// specifically to apply to the flow-controlled implementation of a unary
-// method
+// method.
+/// The argument to the constructor should be a member function already
+/// bound to the appropriate service instance. The declaration gets too complicated
+/// otherwise.
template <class ServiceType, class RequestType, class ResponseType>
class FCUnaryMethodHandler : public MethodHandler {
public:
- FCUnaryMethodHandler(std::function<Status(ServiceType*, ServerContext*,
+ FCUnaryMethodHandler(std::function<Status(ServerContext*,
FCUnary<RequestType,ResponseType>*)>
- func, ServiceType* service)
- : func_(func), service_(service) {}
+ func)
+ : func_(func) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
FCUnary<RequestType, ResponseType> fc_unary(param.call,
param.server_context);
- Status status = func_(service_, param.server_context, &fc_unary);
+ Status status = func_(param.server_context, &fc_unary);
if (!param.server_context->sent_initial_metadata_) {
// means that the write never happened, which is bad
} else {
@@ -216,12 +219,10 @@ class FCUnaryMethodHandler : public MethodHandler {
}
}
private:
- // Application provided rpc handler function.
- std::function<Status(ServiceType*, ServerContext*,
+ // Application provided rpc handler function, already bound to its service.
+ std::function<Status(ServerContext*,
FCUnary<RequestType, ResponseType>*)>
func_;
- // The class the above handler function lives in.
- ServiceType* service_;
};
// Handle unknown method by returning UNIMPLEMENTED error.
diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h
index a1e1ed176f..8a925d8037 100644
--- a/include/grpc++/impl/codegen/server_context.h
+++ b/include/grpc++/impl/codegen/server_context.h
@@ -67,6 +67,8 @@ template <class W>
class ServerWriter;
template <class W, class R>
class ServerReaderWriter;
+template <class Req, class Resp>
+class FCUnary;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@@ -75,6 +77,8 @@ template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class FCUnaryMethodHandler;
class UnknownMethodHandler;
class Call;
@@ -177,6 +181,8 @@ class ServerContext {
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::ServerReaderWriter;
+ template <class Req, class Resp>
+ friend class ::grpc::FCUnary;
template <class ServiceType, class RequestType, class ResponseType>
friend class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@@ -185,6 +191,8 @@ class ServerContext {
friend class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class BidiStreamingHandler;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class FCUnaryMethodHandler;
friend class UnknownMethodHandler;
friend class ::grpc::ClientContext;
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index da89d433b1..9b493fe926 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -626,11 +626,11 @@ void PrintHeaderServerMethodFCUnary(
printer->Indent();
printer->Print(*vars,
"WithFCUnaryMethod_$Method$() {\n"
- " ::grpc::Status (*fn)(::grpc::ServerContext*, ::grpc::FCUnary< $Request$,$Response$>*) = this->WithFCUnaryMethod_$Method$<BaseClass>::$Method$;\n"
" ::grpc::Service::MarkMethodFCUnary($Idx$,\n"
" new ::grpc::FCUnaryMethodHandler<Service, "
"$Request$, "
- "$Response$>(fn, this));\n"
+ "$Response$>("
+ "std::bind(&WithFCUnaryMethod_$Method$<BaseClass>::FC$Method$, this, std::placeholders::_1, std::placeholders::_2)));\n"
"}\n");
printer->Print(*vars,
"~WithFCUnaryMethod_$Method$() GRPC_OVERRIDE {\n"
@@ -648,9 +648,9 @@ void PrintHeaderServerMethodFCUnary(
printer->Print(
*vars,
"// replace default version of this method with FCUnary\n"
- "::grpc::Status $Method$("
+ "virtual ::grpc::Status FC$Method$("
"::grpc::ServerContext* context, ::grpc::FCUnary< $Request$,$Response$>* fc_unary)"
- " GRPC_FINAL GRPC_OVERRIDE;\n");
+ " = 0;\n");
printer->Outdent();
printer->Print(*vars, "};\n");
}
diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc
index 7e0c0e8a7c..699cf49b26 100644
--- a/test/cpp/end2end/hybrid_end2end_test.cc
+++ b/test/cpp/end2end/hybrid_end2end_test.cc
@@ -199,7 +199,7 @@ class HybridEnd2endTest : public ::testing::Test {
HybridEnd2endTest() {}
void SetUpServer(::grpc::Service* service1, ::grpc::Service* service2,
- AsyncGenericService* generic_service) {
+ AsyncGenericService* generic_service, int max_message_size = 0) {
int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port;
@@ -217,6 +217,11 @@ class HybridEnd2endTest : public ::testing::Test {
if (generic_service) {
builder.RegisterAsyncGenericService(generic_service);
}
+
+ if (max_message_size != 0) {
+ builder.SetMaxMessageSize(max_message_size);
+ }
+
// Create a separate cq for each potential handler.
for (int i = 0; i < 5; i++) {
cqs_.push_back(builder.AddCompletionQueue(false));
@@ -415,6 +420,38 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_SyncDupService) {
request_stream_handler_thread.join();
}
+// Add a second service with one sync FCUnary method.
+class FCUnaryDupPkg : public duplicate::EchoTestService::WithFCUnaryMethod_Echo<TestServiceImplDupPkg> {
+public:
+ Status FCEcho(ServerContext* context, FCUnary<EchoRequest,EchoResponse>* fc_unary) GRPC_OVERRIDE {
+ EchoRequest req;
+ EchoResponse resp;
+ gpr_log(GPR_INFO, "FC Unary Next Message Size is %u", fc_unary->NextMessageSize());
+ GPR_ASSERT(fc_unary->Read(&req));
+ resp.set_message(req.message() + "_dup");
+ GPR_ASSERT(fc_unary->Write(resp));
+ return Status::OK;
+ }
+};
+
+TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_SyncFCUnaryDupService) {
+ typedef EchoTestService::WithAsyncMethod_RequestStream<
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>>
+ SType;
+ SType service;
+ FCUnaryDupPkg dup_service;
+ SetUpServer(&service, &dup_service, nullptr, 8192);
+ ResetStub();
+ std::thread response_stream_handler_thread(HandleServerStreaming<SType>,
+ &service, cqs_[0].get());
+ std::thread request_stream_handler_thread(HandleClientStreaming<SType>,
+ &service, cqs_[1].get());
+ TestAllMethods();
+ SendEchoToDupService();
+ response_stream_handler_thread.join();
+ request_stream_handler_thread.join();
+}
+
// Add a second service with one async method.
TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) {
typedef EchoTestService::WithAsyncMethod_RequestStream<