From 780d13cefa7335544146a52b1b93a833381512df Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Mon, 30 May 2022 17:09:56 -0500 Subject: [PATCH] Refactoring refresh capability to provider manager in preparation for level 3 refresh --- .../scwx/qt/manager/radar_product_manager.cpp | 139 ++++++++++++------ .../scwx/qt/manager/radar_product_manager.hpp | 5 +- scwx-qt/source/scwx/qt/map/map_widget.cpp | 12 +- 3 files changed, 102 insertions(+), 54 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp index 94fc73d7..b303418a 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp @@ -62,6 +62,56 @@ static std::mutex fileLoadMutex_; class RadarProductManagerImpl { public: + struct ProviderManager + { + explicit ProviderManager(common::RadarProductGroup group) : + ProviderManager(group, "???") + { + } + explicit ProviderManager(common::RadarProductGroup group, + const std::string& product) : + group_ {group}, + product_ {product}, + refreshEnabled_ {false}, + refreshTimer_ {util::io_context()}, + refreshTimerMutex_ {}, + provider_ {nullptr} + { + } + ~ProviderManager() = default; + + void Disable() + { + std::unique_lock lock(refreshTimerMutex_); + refreshEnabled_ = false; + refreshTimer_.cancel(); + } + + std::string name() const + { + std::string name; + + if (group_ == common::RadarProductGroup::Level3) + { + name = std::format( + "{}, {}", common::GetRadarProductGroupName(group_), product_); + } + else + { + name = common::GetRadarProductGroupName(group_); + } + + return name; + } + + const common::RadarProductGroup group_; + const std::string product_; + bool refreshEnabled_; + boost::asio::steady_timer refreshTimer_; + std::mutex refreshTimerMutex_; + std::shared_ptr provider_; + }; + explicit RadarProductManagerImpl(RadarProductManager* self, const std::string& radarId) : self_ {self}, @@ -74,12 +124,8 @@ public: level3ProductRecords_ {}, level2ProductRecordMutex_ {}, level3ProductRecordMutex_ {}, - level2DataRefreshEnabled_ {false}, - level2DataRefreshTimer_ {util::io_context()}, - level2DataRefreshTimerMutex_ {}, - level2DataProvider_ { - provider::NexradDataProviderFactory::CreateLevel2DataProvider( - radarId)}, + level2Data_ { + std::make_shared(common::RadarProductGroup::Level2)}, initializeMutex_ {}, loadLevel2DataMutex_ {} { @@ -88,19 +134,15 @@ public: logger_->warn("Radar site not found: \"{}\"", radarId_); radarSite_ = std::make_shared(); } + + level2Data_->provider_ = + provider::NexradDataProviderFactory::CreateLevel2DataProvider(radarId); } - ~RadarProductManagerImpl() - { - { - std::unique_lock lock(level2DataRefreshTimerMutex_); - level2DataRefreshEnabled_ = false; - level2DataRefreshTimer_.cancel(); - } - } + ~RadarProductManagerImpl() { level2Data_->Disable(); } RadarProductManager* self_; - void RefreshLevel2Data(); + void RefreshData(std::shared_ptr provider); std::shared_ptr GetLevel2ProductRecord(std::chrono::system_clock::time_point time); @@ -129,10 +171,7 @@ public: std::shared_mutex level2ProductRecordMutex_; std::shared_mutex level3ProductRecordMutex_; - bool level2DataRefreshEnabled_; - boost::asio::steady_timer level2DataRefreshTimer_; - std::mutex level2DataRefreshTimerMutex_; - std::shared_ptr level2DataProvider_; + std::shared_ptr level2Data_; std::mutex initializeMutex_; std::mutex loadLevel2DataMutex_; @@ -281,40 +320,41 @@ void RadarProductManager::Initialize() void RadarProductManager::EnableLevel2Refresh(bool enabled) { - if (p->level2DataRefreshEnabled_ != enabled) + if (p->level2Data_->refreshEnabled_ != enabled) { - p->level2DataRefreshEnabled_ = enabled; + p->level2Data_->refreshEnabled_ = enabled; if (enabled) { - p->RefreshLevel2Data(); + p->RefreshData(p->level2Data_); } } } -void RadarProductManagerImpl::RefreshLevel2Data() +void RadarProductManagerImpl::RefreshData( + std::shared_ptr provider) { - logger_->debug("RefreshLevel2Data()"); + logger_->debug("RefreshData: {}", provider->name()); { - std::unique_lock lock(level2DataRefreshTimerMutex_); - level2DataRefreshTimer_.cancel(); + std::unique_lock lock(provider->refreshTimerMutex_); + provider->refreshTimer_.cancel(); } util::async( - [&]() + [=]() { - auto [newObjects, totalObjects] = level2DataProvider_->Refresh(); + auto [newObjects, totalObjects] = provider->provider_->Refresh(); std::chrono::milliseconds interval = kRetryInterval_; if (newObjects > 0) { - std::string key = level2DataProvider_->FindLatestKey(); - auto latestTime = level2DataProvider_->GetTimePointByKey(key); + std::string key = provider->provider_->FindLatestKey(); + auto latestTime = provider->provider_->GetTimePointByKey(key); - auto updatePeriod = level2DataProvider_->update_period(); - auto lastModified = level2DataProvider_->last_modified(); + auto updatePeriod = provider->provider_->update_period(); + auto lastModified = provider->provider_->last_modified(); interval = std::chrono::duration_cast( updatePeriod - (std::chrono::system_clock::now() - lastModified)); @@ -323,39 +363,44 @@ void RadarProductManagerImpl::RefreshLevel2Data() interval = kRetryInterval_; } - emit self_->NewLevel2DataAvailable(latestTime); + emit self_->NewDataAvailable( + provider->group_, provider->product_, latestTime); } - else if (level2DataRefreshEnabled_ && totalObjects == 0) + else if (provider->refreshEnabled_ && totalObjects == 0) { - logger_->info("No level 2 data found, disabling refresh"); + logger_->info("[{}] No data found, disabling refresh", + provider->name()); - level2DataRefreshEnabled_ = false; + provider->refreshEnabled_ = false; } - if (level2DataRefreshEnabled_) + if (provider->refreshEnabled_) { - std::unique_lock lock(level2DataRefreshTimerMutex_); + std::unique_lock lock(provider->refreshTimerMutex_); logger_->debug( - "Scheduled refresh in {:%M:%S}", + "[{}] Scheduled refresh in {:%M:%S}", + provider->name(), std::chrono::duration_cast(interval)); { - level2DataRefreshTimer_.expires_after(interval); - level2DataRefreshTimer_.async_wait( - [this](const boost::system::error_code& e) + provider->refreshTimer_.expires_after(interval); + provider->refreshTimer_.async_wait( + [=](const boost::system::error_code& e) { if (e == boost::system::errc::success) { - RefreshLevel2Data(); + RefreshData(provider); } else if (e == boost::asio::error::operation_aborted) { - logger_->debug("Level 2 data refresh timer cancelled"); + logger_->debug("[{}] Data refresh timer cancelled", + provider->name()); } else { - logger_->warn("Level 2 data refresh timer error: {}", + logger_->warn("[{}] Data refresh timer error: {}", + provider->name(), e.message()); } }); @@ -391,8 +436,8 @@ void RadarProductManager::LoadLevel2Data( if (existingRecord == nullptr) { - std::string key = p->level2DataProvider_->FindKey(time); - nexradFile = p->level2DataProvider_->LoadObjectByKey(key); + std::string key = p->level2Data_->provider_->FindKey(time); + nexradFile = p->level2Data_->provider_->LoadObjectByKey(key); } else { diff --git a/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp b/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp index 191143f8..d796f2b3 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.hpp @@ -64,8 +64,9 @@ public: std::shared_ptr request = nullptr); signals: - void - NewLevel2DataAvailable(std::chrono::system_clock::time_point latestTime); + void NewDataAvailable(common::RadarProductGroup group, + const std::string& product, + std::chrono::system_clock::time_point latestTime); private: std::unique_ptr p; diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index c8205c79..1a027b50 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -603,13 +603,15 @@ void MapWidgetImpl::AutoRefreshConnect() { connect( radarProductManager_.get(), - &manager::RadarProductManager::NewLevel2DataAvailable, + &manager::RadarProductManager::NewDataAvailable, this, - [&](std::chrono::system_clock::time_point latestTime) + [&](common::RadarProductGroup group, + const std::string& product, + std::chrono::system_clock::time_point latestTime) { if (autoRefreshEnabled_ && context_->radarProductView_ != nullptr && - context_->radarProductView_->GetRadarProductGroup() == - common::RadarProductGroup::Level2) + group == common::RadarProductGroup::Level2 && + context_->radarProductView_->GetRadarProductGroup() == group) { // Create file request std::shared_ptr request = @@ -646,7 +648,7 @@ void MapWidgetImpl::AutoRefreshDisconnect() if (radarProductManager_ != nullptr) { disconnect(radarProductManager_.get(), - &manager::RadarProductManager::NewLevel2DataAvailable, + &manager::RadarProductManager::NewDataAvailable, this, nullptr); }