1 // 2 // Copyright 2022 gRPC authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef GRPC_SRC_CORE_LOAD_BALANCING_OOB_BACKEND_METRIC_INTERNAL_H 18 #define GRPC_SRC_CORE_LOAD_BALANCING_OOB_BACKEND_METRIC_INTERNAL_H 19 20 #include <grpc/support/port_platform.h> 21 22 #include <memory> 23 #include <set> 24 #include <utility> 25 26 #include "absl/base/thread_annotations.h" 27 #include "absl/strings/string_view.h" 28 29 #include <grpc/impl/connectivity_state.h> 30 31 #include "src/core/client_channel/subchannel.h" 32 #include "src/core/client_channel/subchannel_interface_internal.h" 33 #include "src/core/client_channel/subchannel_stream_client.h" 34 #include "src/core/lib/gprpp/orphanable.h" 35 #include "src/core/lib/gprpp/ref_counted_ptr.h" 36 #include "src/core/lib/gprpp/sync.h" 37 #include "src/core/lib/gprpp/time.h" 38 #include "src/core/lib/gprpp/unique_type_name.h" 39 #include "src/core/load_balancing/backend_metric_data.h" 40 #include "src/core/load_balancing/oob_backend_metric.h" 41 42 namespace grpc_core { 43 44 class OrcaWatcher; 45 46 // This producer is registered with a subchannel. It creates a 47 // streaming ORCA call and reports the resulting backend metrics to all 48 // registered watchers. 49 class OrcaProducer final : public Subchannel::DataProducerInterface { 50 public: 51 void Start(RefCountedPtr<Subchannel> subchannel); 52 Type()53 static UniqueTypeName Type() { 54 static UniqueTypeName::Factory kFactory("orca"); 55 return kFactory.Create(); 56 } 57 type()58 UniqueTypeName type() const override { return Type(); } 59 60 // Adds and removes watchers. 61 void AddWatcher(OrcaWatcher* watcher); 62 void RemoveWatcher(OrcaWatcher* watcher); 63 64 private: 65 class ConnectivityWatcher; 66 class OrcaStreamEventHandler; 67 68 void Orphaned() override; 69 70 // Returns the minimum requested reporting interval across all watchers. 71 Duration GetMinIntervalLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(&mu_); 72 73 // Starts a new stream if we have a connected subchannel. 74 // Called whenever the reporting interval changes or the subchannel 75 // transitions to state READY. 76 void MaybeStartStreamLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&mu_); 77 78 // Handles a connectivity state change on the subchannel. 79 void OnConnectivityStateChange(grpc_connectivity_state state); 80 81 // Called to notify watchers of a new backend metric report. 82 void NotifyWatchers(const BackendMetricData& backend_metric_data); 83 84 RefCountedPtr<Subchannel> subchannel_; 85 RefCountedPtr<ConnectedSubchannel> connected_subchannel_; 86 ConnectivityWatcher* connectivity_watcher_; 87 Mutex mu_; 88 std::set<OrcaWatcher*> watchers_ ABSL_GUARDED_BY(mu_); 89 Duration report_interval_ ABSL_GUARDED_BY(mu_) = Duration::Infinity(); 90 OrphanablePtr<SubchannelStreamClient> stream_client_ ABSL_GUARDED_BY(mu_); 91 }; 92 93 // This watcher is returned to the LB policy and added to the 94 // client channel SubchannelWrapper. 95 class OrcaWatcher final : public InternalSubchannelDataWatcherInterface { 96 public: OrcaWatcher(Duration report_interval,std::unique_ptr<OobBackendMetricWatcher> watcher)97 OrcaWatcher(Duration report_interval, 98 std::unique_ptr<OobBackendMetricWatcher> watcher) 99 : report_interval_(report_interval), watcher_(std::move(watcher)) {} 100 ~OrcaWatcher() override; 101 report_interval()102 Duration report_interval() const { return report_interval_; } watcher()103 OobBackendMetricWatcher* watcher() const { return watcher_.get(); } 104 type()105 UniqueTypeName type() const override { return OrcaProducer::Type(); } 106 107 // When the client channel sees this wrapper, it will pass it the real 108 // subchannel to use. 109 void SetSubchannel(Subchannel* subchannel) override; 110 111 private: 112 const Duration report_interval_; 113 std::unique_ptr<OobBackendMetricWatcher> watcher_; 114 RefCountedPtr<OrcaProducer> producer_; 115 }; 116 117 } // namespace grpc_core 118 119 #endif // GRPC_SRC_CORE_LOAD_BALANCING_OOB_BACKEND_METRIC_INTERNAL_H 120