diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 1a62df5698f..f5fc51ed1ff 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -56,6 +56,7 @@ class AsyncGenericService; class RpcService; class RpcServiceMethod; class ServerAsyncStreamingInterface; +class ServerContext; class ThreadPoolInterface; /// Models a gRPC server. @@ -84,6 +85,17 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook { /// call \a Shutdown for this function to ever return. void Wait(); + /// Global Callbacks + /// + /// Can be set exactly once per application to install hooks whenever + /// a server event occurs + class GlobalCallbacks { + public: + virtual void PreSynchronousRequest(ServerContext* context) = 0; + virtual void PostSynchronousRequest(ServerContext* context) = 0; + }; + static void SetGlobalCallbacks(GlobalCallbacks* callbacks); + private: friend class AsyncGenericService; friend class AsynchronousService; diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 695e8116548..7b51c56f0d3 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -51,6 +51,15 @@ namespace grpc { +class DefaultGlobalCallbacks GRPC_FINAL : public Server::GlobalCallbacks { + public: + void PreSynchronousRequest(ServerContext* context) GRPC_OVERRIDE {} + void PostSynchronousRequest(ServerContext* context) GRPC_OVERRIDE {} +}; + +static DefaultGlobalCallbacks g_default_callbacks; +static Server::GlobalCallbacks* g_callbacks = &g_default_callbacks; + class Server::UnimplementedAsyncRequestContext { protected: UnimplementedAsyncRequestContext() : generic_stream_(&server_context_) {} @@ -220,8 +229,10 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag { void Run() { ctx_.BeginCompletionOp(&call_); + g_callbacks->PreSynchronousRequest(&ctx_); method_->handler()->RunHandler(MethodHandler::HandlerParameter( &call_, &ctx_, request_payload_, call_.max_message_size())); + g_callbacks->PostSynchronousRequest(&ctx_); request_payload_ = nullptr; void* ignored_tag; bool ignored_ok; @@ -304,6 +315,13 @@ Server::~Server() { delete sync_methods_; } +void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { + GPR_ASSERT(g_callbacks == &g_default_callbacks); + GPR_ASSERT(callbacks != NULL); + GPR_ASSERT(callbacks != &g_default_callbacks); + g_callbacks = callbacks; +} + bool Server::RegisterService(const grpc::string* host, RpcService* service) { for (int i = 0; i < service->GetMethodCount(); ++i) { RpcServiceMethod* method = service->GetMethod(i);