#include #include #include #include #include #include #include namespace c10::monitor { namespace detail { namespace { using GaugeBackendFactories = std::vector>; Synchronized& gaugeBackendFactories() { static auto instance = new Synchronized(); return *instance; } } // namespace class GaugeImpl { public: static GaugeImpl& getInstance(std::string_view key) { static auto& implMapSynchronized = *new Synchronized< std::unordered_map>>(); return *implMapSynchronized.withLock([&](auto& implMap) { if (auto implIt = implMap.find(std::string(key)); implIt != implMap.end()) { return implIt->second.get(); } auto [implIt, emplaceSuccess] = implMap.emplace( std::string{key}, std::unique_ptr(new GaugeImpl(key))); assert(emplaceSuccess); return implIt->second.get(); }); } void record(int64_t value) { for (auto& backend : backends_) { backend->record(value); } } private: explicit GaugeImpl(std::string_view key) { auto factoriesCopy = gaugeBackendFactories().withLock( [](auto& factories) { return factories; }); for (const auto& factory : factoriesCopy) { if (auto backend = factory->create(key)) { backends_.push_back(std::move(backend)); } } } SmallVector> backends_; }; void registerGaugeBackend(std::unique_ptr backend) { gaugeBackendFactories().withLock( [&](auto& backends) { backends.push_back(std::move(backend)); }); } } // namespace detail GaugeHandle::GaugeHandle(std::string_view key) : impl_(detail::GaugeImpl::getInstance(key)) {} void GaugeHandle::record(int64_t value) { impl_.record(value); } } // namespace c10::monitor