// // // Copyright 2020 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // #ifndef GRPCPP_XDS_SERVER_BUILDER_H #define GRPCPP_XDS_SERVER_BUILDER_H #include #include #include "src/core/ext/xds/xds_enabled_server.h" namespace grpc { class XdsServerServingStatusNotifierInterface { public: struct ServingStatusUpdate { grpc::Status status; }; virtual ~XdsServerServingStatusNotifierInterface() = default; // \a uri contains the listening target associated with the notification. Note // that a single target provided to XdsServerBuilder can get resolved to // multiple listening addresses. // The callback is invoked each time there is an update to the serving status. // The API does not provide any guarantees around duplicate updates. // Status::OK signifies that the server is serving, while a non-OK status // signifies that the server is not serving. virtual void OnServingStatusUpdate(std::string uri, ServingStatusUpdate update) = 0; }; class XdsServerBuilder : public grpc::ServerBuilder { public: // NOTE: class experimental_type is not part of the public API of this class // TODO(yashykt): Integrate into public API when this is no longer // experimental. class experimental_type : public grpc::ServerBuilder::experimental_type { public: explicit experimental_type(XdsServerBuilder* builder) : ServerBuilder::experimental_type(builder), builder_(builder) {} // EXPERIMENTAL: Sets the drain grace period in ms for older connections // when updates to a Listener is received. void set_drain_grace_time(int drain_grace_time_ms) { builder_->drain_grace_time_ms_ = drain_grace_time_ms; } private: XdsServerBuilder* builder_; }; // It is the responsibility of the application to make sure that \a notifier // outlasts the life of the server. Notifications will start being made // asynchronously once `BuildAndStart()` has been called. Note that it is // possible for notifications to be made before `BuildAndStart()` returns. void set_status_notifier(XdsServerServingStatusNotifierInterface* notifier) { notifier_ = notifier; } /// 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. experimental_type experimental() { return experimental_type(this); } private: // Called at the beginning of BuildAndStart(). ChannelArguments BuildChannelArgs() override { ChannelArguments args = ServerBuilder::BuildChannelArgs(); if (drain_grace_time_ms_ >= 0) { args.SetInt(GRPC_ARG_SERVER_CONFIG_CHANGE_DRAIN_GRACE_TIME_MS, drain_grace_time_ms_); } args.SetInt(GRPC_ARG_XDS_ENABLED_SERVER, 1); grpc_channel_args c_channel_args = args.c_channel_args(); grpc_server_config_fetcher* fetcher = grpc_server_config_fetcher_xds_create( {OnServingStatusUpdate, notifier_}, &c_channel_args); if (fetcher != nullptr) set_fetcher(fetcher); return args; } static void OnServingStatusUpdate(void* user_data, const char* uri, grpc_serving_status_update update) { if (user_data == nullptr) return; XdsServerServingStatusNotifierInterface* notifier = static_cast(user_data); notifier->OnServingStatusUpdate( uri, {grpc::Status(static_cast(update.code), update.error_message)}); } XdsServerServingStatusNotifierInterface* notifier_ = nullptr; int drain_grace_time_ms_ = -1; }; } // namespace grpc #endif // GRPCPP_XDS_SERVER_BUILDER_H