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

@ -51,8 +51,15 @@ namespace internal {
class ServerAsyncStreamingInterface; class ServerAsyncStreamingInterface;
} // namespace internal } // namespace internal
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
namespace experimental { namespace experimental {
#endif
class CallbackGenericService; class CallbackGenericService;
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
} // namespace experimental
#endif
namespace experimental {
class ServerInterceptorFactoryInterface; class ServerInterceptorFactoryInterface;
} // namespace experimental } // namespace experimental
@ -124,6 +131,14 @@ class ServerInterface : public internal::CallHook {
/// service. The service must exist for the lifetime of the Server instance. /// service. The service must exist for the lifetime of the Server instance.
virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0; 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 /// NOTE: class experimental_registration_interface is not part of the public
/// API of this class /// API of this class
/// TODO(vjpai): Move these contents to public API when no longer experimental /// 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() { virtual experimental_registration_interface* experimental_registration() {
return nullptr; return nullptr;
} }
#endif
/// Tries to bind \a server to the given \a addr. /// Tries to bind \a server to the given \a addr.
/// ///

@ -57,9 +57,15 @@ namespace internal {
class ExternalConnectionAcceptorImpl; class ExternalConnectionAcceptorImpl;
} // namespace internal } // namespace internal
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
namespace experimental { namespace experimental {
#endif
class CallbackGenericService; class CallbackGenericService;
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
} // namespace experimental
#endif
namespace experimental {
// EXPERIMENTAL API: // EXPERIMENTAL API:
// Interface for a grpc server to build transports with connections created out // Interface for a grpc server to build transports with connections created out
// of band. // of band.
@ -265,12 +271,14 @@ class ServerBuilder {
builder_->interceptor_creators_ = std::move(interceptor_creators); builder_->interceptor_creators_ = std::move(interceptor_creators);
} }
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
/// Register a generic service that uses the callback API. /// Register a generic service that uses the callback API.
/// Matches requests with any :authority /// Matches requests with any :authority
/// This is mostly useful for writing generic gRPC Proxies where the exact /// This is mostly useful for writing generic gRPC Proxies where the exact
/// serialization format is unknown /// serialization format is unknown
ServerBuilder& RegisterCallbackGenericService( ServerBuilder& RegisterCallbackGenericService(
grpc::experimental::CallbackGenericService* service); grpc::experimental::CallbackGenericService* service);
#endif
enum class ExternalConnectionType { enum class ExternalConnectionType {
FROM_FD = 0 // in the form of a file descriptor FROM_FD = 0 // in the form of a file descriptor
@ -288,6 +296,15 @@ class ServerBuilder {
ServerBuilder* builder_; 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 /// 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 /// to the experimental components of this class. It may be changed or removed
/// at any time. /// at any time.
@ -369,8 +386,13 @@ class ServerBuilder {
std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_; std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_;
grpc_resource_quota* resource_quota_; grpc_resource_quota* resource_quota_;
grpc::AsyncGenericService* generic_service_{nullptr}; grpc::AsyncGenericService* generic_service_{nullptr};
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
grpc::CallbackGenericService* callback_generic_service_{nullptr};
#else
grpc::experimental::CallbackGenericService* callback_generic_service_{ grpc::experimental::CallbackGenericService* callback_generic_service_{
nullptr}; nullptr};
#endif
struct { struct {
bool is_set; bool is_set;
grpc_compression_level level; 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. /// service. The service must exist for the lifetime of the Server instance.
void RegisterAsyncGenericService(grpc::AsyncGenericService* service) override; 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 /// NOTE: class experimental_registration_type is not part of the public API
/// of this class /// of this class
/// TODO(vjpai): Move these contents to the public API of Server when /// 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 { experimental_registration_interface* experimental_registration() override {
return &experimental_registration_; return &experimental_registration_;
} }
#endif
void PerformOpsOnCall(grpc::internal::CallOpSetInterface* ops, void PerformOpsOnCall(grpc::internal::CallOpSetInterface* ops,
grpc::internal::Call* call) override; 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. // List of callback requests to start when server actually starts.
std::list<CallbackRequestBase*> callback_reqs_to_start_; std::list<CallbackRequestBase*> callback_reqs_to_start_;
#ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
// For registering experimental callback generic service; remove when that // For registering experimental callback generic service; remove when that
// method longer experimental // method longer experimental
experimental_registration_type experimental_registration_{this}; experimental_registration_type experimental_registration_{this};
#endif
// Server status // Server status
grpc::internal::Mutex mu_; 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 // When appropriate, use a default callback generic service to handle
// unimplemented methods // unimplemented methods
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
std::unique_ptr<grpc::CallbackGenericService> unimplemented_service_;
#else
std::unique_ptr<grpc::experimental::CallbackGenericService> std::unique_ptr<grpc::experimental::CallbackGenericService>
unimplemented_service_; unimplemented_service_;
#endif
// A special handler for resource exhausted in sync case // A special handler for resource exhausted in sync case
std::unique_ptr<grpc::internal::MethodHandler> resource_exhausted_handler_; std::unique_ptr<grpc::internal::MethodHandler> resource_exhausted_handler_;

@ -101,6 +101,20 @@ ServerBuilder& ServerBuilder::RegisterAsyncGenericService(
return *this; 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( ServerBuilder& ServerBuilder::experimental_type::RegisterCallbackGenericService(
grpc::experimental::CallbackGenericService* service) { grpc::experimental::CallbackGenericService* service) {
if (builder_->generic_service_ || builder_->callback_generic_service_) { if (builder_->generic_service_ || builder_->callback_generic_service_) {
@ -113,6 +127,7 @@ ServerBuilder& ServerBuilder::experimental_type::RegisterCallbackGenericService(
} }
return *builder_; return *builder_;
} }
#endif
std::unique_ptr<grpc::experimental::ExternalConnectionAcceptor> std::unique_ptr<grpc::experimental::ExternalConnectionAcceptor>
ServerBuilder::experimental_type::AddExternalConnectionAcceptor( ServerBuilder::experimental_type::AddExternalConnectionAcceptor(

@ -106,6 +106,14 @@ class UnimplementedAsyncRequestContext {
GenericServerAsyncReaderWriter generic_stream_; 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 } // namespace
ServerInterface::BaseAsyncRequest::BaseAsyncRequest( ServerInterface::BaseAsyncRequest::BaseAsyncRequest(
@ -805,8 +813,9 @@ bool Server::CallbackRequest<grpc::experimental::CallbackServerContext>::
} }
template <> template <>
bool Server::CallbackRequest<grpc::experimental::GenericCallbackServerContext>:: bool Server::CallbackRequest<
FinalizeResult(void** /*tag*/, bool* status) { grpc::GenericCallbackServerContext>::FinalizeResult(void** /*tag*/,
bool* status) {
if (*status) { if (*status) {
// TODO(yangg) remove the copy here // TODO(yangg) remove the copy here
ctx_.method_ = grpc::StringFromCopiedSlice(call_details_->method); ctx_.method_ = grpc::StringFromCopiedSlice(call_details_->method);
@ -825,7 +834,7 @@ const char* Server::CallbackRequest<
template <> template <>
const char* Server::CallbackRequest< const char* Server::CallbackRequest<
grpc::experimental::GenericCallbackServerContext>::method_name() const { grpc::GenericCallbackServerContext>::method_name() const {
return ctx_.method().c_str(); return ctx_.method().c_str();
} }
@ -1161,7 +1170,7 @@ void Server::RegisterAsyncGenericService(grpc::AsyncGenericService* service) {
} }
void Server::RegisterCallbackGenericService( void Server::RegisterCallbackGenericService(
grpc::experimental::CallbackGenericService* service) { grpc::CallbackGenericService* service) {
GPR_ASSERT( GPR_ASSERT(
service->server_ == nullptr && service->server_ == nullptr &&
"Can only register a callback generic service against one server."); "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 // TODO(vjpai): Register these dynamically based on need
for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) {
callback_reqs_to_start_.push_back( callback_reqs_to_start_.push_back(
new CallbackRequest<grpc::experimental::GenericCallbackServerContext>( new CallbackRequest<grpc::GenericCallbackServerContext>(
this, method_index, nullptr, nullptr)); 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 // service to handle any unimplemented methods using the default reactor
// creator // creator
if (!callback_reqs_to_start_.empty() && !has_callback_generic_service_) { if (!callback_reqs_to_start_.empty() && !has_callback_generic_service_) {
unimplemented_service_.reset( unimplemented_service_.reset(new grpc::CallbackGenericService);
new grpc::experimental::CallbackGenericService);
RegisterCallbackGenericService(unimplemented_service_.get()); RegisterCallbackGenericService(unimplemented_service_.get());
} }

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

Loading…
Cancel
Save