Merge branch 'c++api' of github.com:ctiller/grpc into c++api

pull/501/head
Yang Gao 10 years ago
commit 9a2743a897
  1. 14
      include/grpc++/impl/service_type.h
  2. 3
      include/grpc++/server.h
  3. 5
      include/grpc++/server_builder.h
  4. 55
      src/compiler/cpp_generator.cc
  5. 34
      src/cpp/server/server.cc
  6. 8
      src/cpp/server/server_builder.cc

@ -37,6 +37,7 @@
namespace grpc {
class RpcService;
class Server;
class SynchronousService {
public:
@ -46,8 +47,17 @@ class SynchronousService {
class AsynchronousService {
public:
virtual ~AsynchronousService() {}
virtual RpcService *service() = 0;
AsynchronousService(CompletionQueue* cq, const char** method_names, size_t method_count) : cq_(cq), method_names_(method_names), method_count_(method_count) {}
CompletionQueue* completion_queue() const { return cq_; }
private:
friend class Server;
CompletionQueue* const cq_;
Server* server_ = nullptr;
const char**const method_names_;
size_t method_count_;
std::vector<void*> request_args_;
};
} // namespace grpc

@ -53,7 +53,7 @@ class Message;
} // namespace google
namespace grpc {
class AsyncServerContext;
class AsynchronousService;
class RpcService;
class RpcServiceMethod;
class ServerCredentials;
@ -79,6 +79,7 @@ class Server final : private CallHook {
// Register a service. This call does not take ownership of the service.
// The service must exist for the lifetime of the Server instance.
bool RegisterService(RpcService* service);
bool RegisterAsyncService(AsynchronousService* service);
// Add a listening port. Can be called multiple times.
int AddPort(const grpc::string& addr);
// Start the server.

@ -42,6 +42,7 @@
namespace grpc {
class AsynchronousService;
class CompletionQueue;
class RpcService;
class Server;
class ServerCredentials;
@ -57,6 +58,10 @@ class ServerBuilder {
// BuildAndStart().
void RegisterService(SynchronousService* service);
// Register an asynchronous service. New calls will be delevered to cq.
// This call does not take ownership of the service or completion queue.
// The service and completion queuemust exist for the lifetime of the Server
// instance returned by BuildAndStart().
void RegisterAsyncService(AsynchronousService* service);
// Add a listening port. Can be called multiple times.

@ -41,10 +41,18 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <sstream>
namespace grpc_cpp_generator {
namespace {
template <class T>
std::string as_string(T x) {
std::ostringstream out;
out << x;
return out.str();
}
bool NoStreaming(const google::protobuf::MethodDescriptor *method) {
return !method->client_streaming() && !method->server_streaming();
}
@ -113,6 +121,7 @@ std::string GetHeaderIncludes(const google::protobuf::FileDescriptor *file) {
"#include <grpc++/status.h>\n"
"\n"
"namespace grpc {\n"
"class CompletionQueue;\n"
"class ChannelInterface;\n"
"class RpcService;\n"
"class ServerContext;\n";
@ -325,16 +334,13 @@ void PrintHeaderService(google::protobuf::io::Printer *printer,
"class AsyncService final : public ::grpc::AsynchronousService {\n"
" public:\n");
printer->Indent();
printer->Print("AsyncService() : service_(nullptr) {}\n");
(*vars)["MethodCount"] = as_string(service->method_count());
printer->Print("explicit AsyncService(::grpc::CompletionQueue* cq);\n");
printer->Print("~AsyncService();\n");
for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderServerMethodAsync(printer, service->method(i), vars);
}
printer->Print("::grpc::RpcService* service() override;\n");
printer->Outdent();
printer->Print(
" private:\n"
" ::grpc::RpcService* service_;\n");
printer->Print("};\n");
printer->Outdent();
@ -369,7 +375,7 @@ void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
"const $Request$& request, $Response$* response) {\n");
printer->Print(*vars,
"return ::grpc::BlockingUnaryCall(channel(),"
"::grpc::RpcMethod(\"/$Package$$Service$/$Method$\"), "
"::grpc::RpcMethod($Service$_method_names[$Idx$]), "
"context, request, response);\n"
"}\n\n");
} else if (ClientOnlyStreaming(method)) {
@ -380,7 +386,7 @@ void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
printer->Print(*vars,
" return new ::grpc::ClientWriter< $Request$>("
"channel(),"
"::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
"::grpc::RpcMethod($Service$_method_names[$Idx$], "
"::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
"context, response);\n"
"}\n\n");
@ -392,7 +398,7 @@ void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
printer->Print(*vars,
" return new ::grpc::ClientReader< $Response$>("
"channel(),"
"::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
"::grpc::RpcMethod($Service$_method_names[$Idx$], "
"::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
"context, *request);\n"
"}\n\n");
@ -405,7 +411,7 @@ void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
*vars,
" return new ::grpc::ClientReaderWriter< $Request$, $Response$>("
"channel(),"
"::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
"::grpc::RpcMethod($Service$_method_names[$Idx$], "
"::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
"context);\n"
"}\n\n");
@ -462,7 +468,8 @@ void PrintSourceServerMethod(google::protobuf::io::Printer *printer,
}
}
void PrintSourceServerAsyncMethod(google::protobuf::io::Printer *printer,
void PrintSourceServerAsyncMethod(
google::protobuf::io::Printer *printer,
const google::protobuf::MethodDescriptor *method,
std::map<std::string, std::string> *vars) {
(*vars)["Method"] = method->name();
@ -494,7 +501,8 @@ void PrintSourceServerAsyncMethod(google::protobuf::io::Printer *printer,
"::grpc::CompletionQueue* cq, void* tag) {\n");
printer->Print("}\n\n");
} else if (BidiStreaming(method)) {
printer->Print(*vars,
printer->Print(
*vars,
"void $Service$::AsyncService::Request$Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
@ -507,6 +515,14 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
const google::protobuf::ServiceDescriptor *service,
std::map<std::string, std::string> *vars) {
(*vars)["Service"] = service->name();
printer->Print(*vars, "static const char* $Service$_method_names[] = {\n");
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["Method"] = service->method(i)->name();
printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
}
printer->Print(*vars, "};\n\n");
printer->Print(
*vars,
"$Service$::Stub* $Service$::NewStub("
@ -516,9 +532,17 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
" return stub;\n"
"};\n\n");
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["Idx"] = as_string(i);
PrintSourceClientMethod(printer, service->method(i), vars);
}
(*vars)["MethodCount"] = as_string(service->method_count());
printer->Print(
*vars,
"$Service$::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : "
"::grpc::AsynchronousService(cq, $Service$_method_names, $MethodCount$) "
"{}\n\n");
printer->Print(*vars,
"$Service$::Service::~Service() {\n"
" delete service_;\n"
@ -537,6 +561,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
printer->Print("service_ = new ::grpc::RpcService();\n");
for (int i = 0; i < service->method_count(); ++i) {
const google::protobuf::MethodDescriptor *method = service->method(i);
(*vars)["Idx"] = as_string(i);
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
@ -546,7 +571,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
" \"/$Package$$Service$/$Method$\",\n"
" $Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::NORMAL_RPC,\n"
" new ::grpc::RpcMethodHandler< $Service$::Service, $Request$, "
"$Response$>(\n"
@ -558,7 +583,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
" \"/$Package$$Service$/$Method$\",\n"
" $Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::CLIENT_STREAMING,\n"
" new ::grpc::ClientStreamingHandler< "
"$Service$::Service, $Request$, $Response$>(\n"
@ -571,7 +596,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
" \"/$Package$$Service$/$Method$\",\n"
" $Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::SERVER_STREAMING,\n"
" new ::grpc::ServerStreamingHandler< "
"$Service$::Service, $Request$, $Response$>(\n"
@ -584,7 +609,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
" \"/$Package$$Service$/$Method$\",\n"
" $Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::BIDI_STREAMING,\n"
" new ::grpc::BidiStreamingHandler< "
"$Service$::Service, $Request$, $Response$>(\n"

@ -39,6 +39,7 @@
#include <grpc/support/log.h>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/rpc_service_method.h>
#include <grpc++/impl/service_type.h>
#include <grpc++/server_context.h>
#include <grpc++/server_credentials.h>
#include <grpc++/thread_pool_interface.h>
@ -56,7 +57,8 @@ Server::Server(ThreadPoolInterface *thread_pool, bool thread_pool_owned,
thread_pool_owned_(thread_pool_owned),
secure_(creds != nullptr) {
if (creds) {
server_ = grpc_secure_server_create(creds->GetRawCreds(), cq_.cq(), nullptr);
server_ =
grpc_secure_server_create(creds->GetRawCreds(), cq_.cq(), nullptr);
} else {
server_ = grpc_server_create(cq_.cq(), nullptr);
}
@ -84,7 +86,8 @@ Server::~Server() {
bool Server::RegisterService(RpcService* service) {
for (int i = 0; i < service->GetMethodCount(); ++i) {
RpcServiceMethod* method = service->GetMethod(i);
void *tag = grpc_server_register_method(server_, method->name(), nullptr, cq_.cq());
void* tag =
grpc_server_register_method(server_, method->name(), nullptr, cq_.cq());
if (!tag) {
gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
method->name());
@ -95,6 +98,23 @@ bool Server::RegisterService(RpcService *service) {
return true;
}
bool Server::RegisterAsyncService(AsynchronousService* service) {
GPR_ASSERT(service->server_ == nullptr && "Can only register an asynchronous service against one server.");
service->server_ = this;
service->request_args_.reserve(service->method_count_);
for (size_t i = 0; i < service->method_count_; ++i) {
void* tag = grpc_server_register_method(server_, service->method_names_[i], nullptr,
service->completion_queue()->cq());
if (!tag) {
gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
service->method_names_[i]);
return false;
}
service->request_args_.push_back(tag);
}
return true;
}
int Server::AddPort(const grpc::string& addr) {
GPR_ASSERT(!started_);
if (secure_) {
@ -136,8 +156,8 @@ class Server::MethodRequestData final : public CompletionQueueTag {
GPR_ASSERT(GRPC_CALL_OK ==
grpc_server_request_registered_call(
server, tag_, &call_, &deadline_, &request_metadata_,
has_request_payload_ ? &request_payload_ : nullptr,
cq_, this));
has_request_payload_ ? &request_payload_ : nullptr, cq_,
this));
}
void FinalizeResult(void** tag, bool* status) override {}
@ -177,6 +197,9 @@ class Server::MethodRequestData final : public CompletionQueueTag {
auto status = method_->handler()->RunHandler(
MethodHandler::HandlerParameter(&call_, &ctx_, req.get(), res.get()));
CallOpBuffer buf;
if (!ctx_.sent_initial_metadata_) {
buf.AddSendInitialMetadata(&ctx_.initial_metadata_);
}
if (has_response_payload_) {
buf.AddSendMessage(*res);
}
@ -249,8 +272,7 @@ void Server::PerformOpsOnCall(CallOpBuffer *buf, Call *call) {
grpc_op ops[MAX_OPS];
buf->FillOps(ops, &nops);
GPR_ASSERT(GRPC_CALL_OK ==
grpc_call_start_batch(call->call(), ops, nops,
buf));
grpc_call_start_batch(call->call(), ops, nops, buf));
}
void Server::ScheduleCallback() {

@ -77,12 +77,18 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
thread_pool_ = new ThreadPool(cores);
thread_pool_owned = true;
}
std::unique_ptr<Server> server(new Server(thread_pool_, thread_pool_owned, creds_.get()));
std::unique_ptr<Server> server(
new Server(thread_pool_, thread_pool_owned, creds_.get()));
for (auto* service : services_) {
if (!server->RegisterService(service)) {
return nullptr;
}
}
for (auto* service : async_services_) {
if (!server->RegisterAsyncService(service)) {
return nullptr;
}
}
for (auto& port : ports_) {
if (!server->AddPort(port)) {
return nullptr;

Loading…
Cancel
Save