De-experimentalize generic features of callback API under an ifdef

pull/21354/head
Vijay Pai 5 years ago
parent 89d317d95c
commit 2c87eaabd4
  1. 9
      include/grpcpp/impl/codegen/server_context_impl.h
  2. 16
      include/grpcpp/impl/codegen/server_interface.h
  3. 22
      include/grpcpp/server_builder_impl.h
  4. 14
      include/grpcpp/server_impl.h
  5. 15
      src/cpp/server/server_builder.cc
  6. 22
      src/cpp/server/server_cc.cc
  7. 27
      test/cpp/end2end/hybrid_end2end_test.cc

@ -95,10 +95,13 @@ namespace grpc {
class GenericServerContext;
class ServerInterface;
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
namespace experimental {
#endif
class GenericCallbackServerContext;
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
} // namespace experimental
#endif
namespace internal {
class Call;
} // namespace internal
@ -348,7 +351,11 @@ class ServerContextBase {
friend class ::grpc_impl::internal::FinishOnlyReactor;
friend class ::grpc_impl::ClientContext;
friend class ::grpc::GenericServerContext;
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
friend class ::grpc::GenericCallbackServerContext;
#else
friend class ::grpc::experimental::GenericCallbackServerContext;
#endif
/// Prevent copying.
ServerContextBase(const ServerContextBase&);

@ -51,8 +51,15 @@ namespace internal {
class ServerAsyncStreamingInterface;
} // namespace internal
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
namespace experimental {
#endif
class CallbackGenericService;
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
} // namespace experimental
#endif
namespace experimental {
class ServerInterceptorFactoryInterface;
} // namespace experimental
@ -124,6 +131,14 @@ class ServerInterface : public internal::CallHook {
/// service. The service must exist for the lifetime of the Server instance.
virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0;
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
/// Register a callback generic service. This call does not take ownership of
/// the service. The service must exist for the lifetime of the Server
/// instance. May not be abstract since this is a post-1.0 API addition.
virtual void RegisterCallbackGenericService(CallbackGenericService*
/*service*/) {}
#else
/// NOTE: class experimental_registration_interface is not part of the public
/// API of this class
/// TODO(vjpai): Move these contents to public API when no longer experimental
@ -142,6 +157,7 @@ class ServerInterface : public internal::CallHook {
virtual experimental_registration_interface* experimental_registration() {
return nullptr;
}
#endif
/// Tries to bind \a server to the given \a addr.
///

@ -57,9 +57,15 @@ namespace internal {
class ExternalConnectionAcceptorImpl;
} // namespace internal
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
namespace experimental {
#endif
class CallbackGenericService;
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
} // namespace experimental
#endif
namespace experimental {
// EXPERIMENTAL API:
// Interface for a grpc server to build transports with connections created out
// of band.
@ -265,12 +271,14 @@ class ServerBuilder {
builder_->interceptor_creators_ = std::move(interceptor_creators);
}
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
/// Register a generic service that uses the callback API.
/// Matches requests with any :authority
/// This is mostly useful for writing generic gRPC Proxies where the exact
/// serialization format is unknown
ServerBuilder& RegisterCallbackGenericService(
grpc::experimental::CallbackGenericService* service);
#endif
enum class ExternalConnectionType {
FROM_FD = 0 // in the form of a file descriptor
@ -288,6 +296,15 @@ class ServerBuilder {
ServerBuilder* builder_;
};
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
/// Register a generic service that uses the callback API.
/// Matches requests with any :authority
/// This is mostly useful for writing generic gRPC Proxies where the exact
/// serialization format is unknown
ServerBuilder& RegisterCallbackGenericService(
grpc::CallbackGenericService* service);
#endif
/// NOTE: The function experimental() is not stable public API. It is a view
/// to the experimental components of this class. It may be changed or removed
/// at any time.
@ -369,8 +386,13 @@ class ServerBuilder {
std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_;
grpc_resource_quota* resource_quota_;
grpc::AsyncGenericService* generic_service_{nullptr};
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
grpc::CallbackGenericService* callback_generic_service_{nullptr};
#else
grpc::experimental::CallbackGenericService* callback_generic_service_{
nullptr};
#endif
struct {
bool is_set;
grpc_compression_level level;

@ -243,6 +243,13 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
/// service. The service must exist for the lifetime of the Server instance.
void RegisterAsyncGenericService(grpc::AsyncGenericService* service) override;
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
/// Register a callback-based generic service. This call does not take
/// ownership of theservice. The service must exist for the lifetime of the
/// Server instance.
void RegisterCallbackGenericService(
grpc::CallbackGenericService* service) override;
#else
/// NOTE: class experimental_registration_type is not part of the public API
/// of this class
/// TODO(vjpai): Move these contents to the public API of Server when
@ -270,6 +277,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
experimental_registration_interface* experimental_registration() override {
return &experimental_registration_;
}
#endif
void PerformOpsOnCall(grpc::internal::CallOpSetInterface* ops,
grpc::internal::Call* call) override;
@ -318,9 +326,11 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
// List of callback requests to start when server actually starts.
std::list<CallbackRequestBase*> callback_reqs_to_start_;
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
// For registering experimental callback generic service; remove when that
// method longer experimental
experimental_registration_type experimental_registration_{this};
#endif
// Server status
grpc::internal::Mutex mu_;
@ -357,8 +367,12 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
// When appropriate, use a default callback generic service to handle
// unimplemented methods
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
std::unique_ptr<grpc::CallbackGenericService> unimplemented_service_;
#else
std::unique_ptr<grpc::experimental::CallbackGenericService>
unimplemented_service_;
#endif
// A special handler for resource exhausted in sync case
std::unique_ptr<grpc::internal::MethodHandler> resource_exhausted_handler_;

@ -101,6 +101,20 @@ ServerBuilder& ServerBuilder::RegisterAsyncGenericService(
return *this;
}
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
ServerBuilder& ServerBuilder::RegisterCallbackGenericService(
grpc::CallbackGenericService* service) {
if (generic_service_ || callback_generic_service_) {
gpr_log(GPR_ERROR,
"Adding multiple generic services is unsupported for now. "
"Dropping the service %p",
(void*)service);
} else {
callback_generic_service_ = service;
}
return *this;
}
#else
ServerBuilder& ServerBuilder::experimental_type::RegisterCallbackGenericService(
grpc::experimental::CallbackGenericService* service) {
if (builder_->generic_service_ || builder_->callback_generic_service_) {
@ -113,6 +127,7 @@ ServerBuilder& ServerBuilder::experimental_type::RegisterCallbackGenericService(
}
return *builder_;
}
#endif
std::unique_ptr<grpc::experimental::ExternalConnectionAcceptor>
ServerBuilder::experimental_type::AddExternalConnectionAcceptor(

@ -106,6 +106,14 @@ class UnimplementedAsyncRequestContext {
GenericServerAsyncReaderWriter generic_stream_;
};
// TODO(b/142832583): Just for this file, use some contents of the experimental
// namespace here to make the code easier to read below. Remove this when
// de-experimentalized fully.
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
using ::grpc::experimental::CallbackGenericService;
using ::grpc::experimental::GenericCallbackServerContext;
#endif
} // namespace
ServerInterface::BaseAsyncRequest::BaseAsyncRequest(
@ -805,8 +813,9 @@ bool Server::CallbackRequest<grpc::experimental::CallbackServerContext>::
}
template <>
bool Server::CallbackRequest<grpc::experimental::GenericCallbackServerContext>::
FinalizeResult(void** /*tag*/, bool* status) {
bool Server::CallbackRequest<
grpc::GenericCallbackServerContext>::FinalizeResult(void** /*tag*/,
bool* status) {
if (*status) {
// TODO(yangg) remove the copy here
ctx_.method_ = grpc::StringFromCopiedSlice(call_details_->method);
@ -825,7 +834,7 @@ const char* Server::CallbackRequest<
template <>
const char* Server::CallbackRequest<
grpc::experimental::GenericCallbackServerContext>::method_name() const {
grpc::GenericCallbackServerContext>::method_name() const {
return ctx_.method().c_str();
}
@ -1161,7 +1170,7 @@ void Server::RegisterAsyncGenericService(grpc::AsyncGenericService* service) {
}
void Server::RegisterCallbackGenericService(
grpc::experimental::CallbackGenericService* service) {
grpc::CallbackGenericService* service) {
GPR_ASSERT(
service->server_ == nullptr &&
"Can only register a callback generic service against one server.");
@ -1174,7 +1183,7 @@ void Server::RegisterCallbackGenericService(
// TODO(vjpai): Register these dynamically based on need
for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) {
callback_reqs_to_start_.push_back(
new CallbackRequest<grpc::experimental::GenericCallbackServerContext>(
new CallbackRequest<grpc::GenericCallbackServerContext>(
this, method_index, nullptr, nullptr));
}
}
@ -1223,8 +1232,7 @@ void Server::Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) {
// service to handle any unimplemented methods using the default reactor
// creator
if (!callback_reqs_to_start_.empty() && !has_callback_generic_service_) {
unimplemented_service_.reset(
new grpc::experimental::CallbackGenericService);
unimplemented_service_.reset(new grpc::CallbackGenericService);
RegisterCallbackGenericService(unimplemented_service_.get());
}

@ -43,6 +43,12 @@ namespace grpc {
namespace testing {
namespace {
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
using ::grpc::experimental::CallbackGenericService;
using ::grpc::experimental::GenericCallbackServerContext;
using ::grpc::experimental::ServerGenericBidiReactor;
#endif
void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
bool VerifyReturnSuccess(CompletionQueue* cq, int i) {
@ -245,11 +251,10 @@ class HybridEnd2endTest : public ::testing::TestWithParam<bool> {
: false;
}
bool SetUpServer(
::grpc::Service* service1, ::grpc::Service* service2,
AsyncGenericService* generic_service,
experimental::CallbackGenericService* callback_generic_service,
int max_message_size = 0) {
bool SetUpServer(::grpc::Service* service1, ::grpc::Service* service2,
AsyncGenericService* generic_service,
CallbackGenericService* callback_generic_service,
int max_message_size = 0) {
int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port;
@ -268,8 +273,12 @@ class HybridEnd2endTest : public ::testing::TestWithParam<bool> {
builder.RegisterAsyncGenericService(generic_service);
}
if (callback_generic_service) {
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
builder.RegisterCallbackGenericService(callback_generic_service);
#else
builder.experimental().RegisterCallbackGenericService(
callback_generic_service);
#endif
}
if (max_message_size != 0) {
@ -807,13 +816,13 @@ TEST_F(HybridEnd2endTest, GenericEcho) {
TEST_P(HybridEnd2endTest, CallbackGenericEcho) {
EchoTestService::WithGenericMethod_Echo<TestServiceImpl> service;
class GenericEchoService : public experimental::CallbackGenericService {
class GenericEchoService : public CallbackGenericService {
private:
experimental::ServerGenericBidiReactor* CreateReactor(
experimental::GenericCallbackServerContext* context) override {
ServerGenericBidiReactor* CreateReactor(
GenericCallbackServerContext* context) override {
EXPECT_EQ(context->method(), "/grpc.testing.EchoTestService/Echo");
class Reactor : public experimental::ServerGenericBidiReactor {
class Reactor : public ServerGenericBidiReactor {
public:
Reactor() { StartRead(&request_); }

Loading…
Cancel
Save