Text event manager should use filtered ranges to request archived products

This commit is contained in:
Dan Paulat 2025-04-13 01:27:47 -05:00
parent e82fa93fb0
commit e3ccce5d5b

View file

@ -15,6 +15,8 @@
#include <boost/asio/post.hpp> #include <boost/asio/post.hpp>
#include <boost/asio/steady_timer.hpp> #include <boost/asio/steady_timer.hpp>
#include <boost/asio/thread_pool.hpp> #include <boost/asio/thread_pool.hpp>
#include <range/v3/view/any_view.hpp>
#include <range/v3/view/filter.hpp>
namespace scwx namespace scwx
{ {
@ -89,18 +91,15 @@ public:
void void
HandleMessage(const std::shared_ptr<awips::TextProductMessage>& message); HandleMessage(const std::shared_ptr<awips::TextProductMessage>& message);
void LoadArchive(std::chrono::sys_days date, const std::string& pil); void LoadArchives(ranges::any_view<std::chrono::sys_days> dates);
void LoadArchives(std::chrono::sys_days date);
void RefreshAsync(); void RefreshAsync();
void Refresh(); void Refresh();
void UpdateArchiveDates(std::chrono::sys_days date); void UpdateArchiveDates(ranges::any_view<std::chrono::sys_days> dates);
// Thread pool sized for: // Thread pool sized for:
// - Live Refresh (1x) // - Live Refresh (1x)
// - Archive Loading (15x) // - Archive Loading (1x)
// - 3 day window (3x) boost::asio::thread_pool threadPool_ {2u};
// - TOR, SVR, SVS, FFW, FFS (5x)
boost::asio::thread_pool threadPool_ {16u};
TextEventManager* self_; TextEventManager* self_;
@ -123,10 +122,8 @@ public:
std::mutex archiveMutex_ {}; std::mutex archiveMutex_ {};
std::list<std::chrono::sys_days> archiveDates_ {}; std::list<std::chrono::sys_days> archiveDates_ {};
std::map< std::map<std::chrono::sys_days,
std::chrono::sys_days, std::vector<std::shared_ptr<awips::TextProductFile>>>
std::unordered_map<std::string,
std::vector<std::shared_ptr<awips::TextProductFile>>>>
archiveMap_; archiveMap_;
boost::uuids::uuid warningsProviderChangedCallbackUuid_ {}; boost::uuids::uuid warningsProviderChangedCallbackUuid_ {};
@ -212,16 +209,17 @@ void TextEventManager::SelectTime(
const auto today = std::chrono::floor<std::chrono::days>(dateTime); const auto today = std::chrono::floor<std::chrono::days>(dateTime);
const auto yesterday = today - std::chrono::days {1}; const auto yesterday = today - std::chrono::days {1};
const auto tomorrow = today + std::chrono::days {1}; const auto tomorrow = today + std::chrono::days {1};
const auto dates = {today, yesterday, tomorrow}; const auto dateArray = std::array {today, yesterday, tomorrow};
for (auto& date : dates) const ranges::any_view<std::chrono::sys_days> dates =
dateArray | ranges::views::filter(
[this](const auto& date)
{ {
if (p->archiveLimit_ == std::chrono::sys_days {} || return p->archiveLimit_ == std::chrono::sys_days {} ||
date < p->archiveLimit_) date < p->archiveLimit_;
{ });
p->LoadArchives(date);
} p->LoadArchives(dates);
}
} }
void TextEventManager::Impl::HandleMessage( void TextEventManager::Impl::HandleMessage(
@ -283,7 +281,8 @@ void TextEventManager::Impl::HandleMessage(
it->second.end(), it->second.end(),
message, message,
[](const std::shared_ptr<awips::TextProductMessage>& a, [](const std::shared_ptr<awips::TextProductMessage>& a,
const std::shared_ptr<awips::TextProductMessage>& b) { const std::shared_ptr<awips::TextProductMessage>& b)
{
return a->wmo_header()->GetDateTime() < return a->wmo_header()->GetDateTime() <
b->wmo_header()->GetDateTime(); b->wmo_header()->GetDateTime();
}); });
@ -302,26 +301,27 @@ void TextEventManager::Impl::HandleMessage(
} }
} }
void TextEventManager::Impl::LoadArchive(std::chrono::sys_days date, void TextEventManager::Impl::LoadArchives(
const std::string& pil) ranges::any_view<std::chrono::sys_days> dates)
{ {
UpdateArchiveDates(dates);
std::unique_lock lock {archiveMutex_}; std::unique_lock lock {archiveMutex_};
auto& dateArchive = archiveMap_[date];
if (dateArchive.contains(pil))
{
// Don't reload data that has already been loaded // Don't reload data that has already been loaded
return; const ranges::any_view<std::chrono::sys_days> filteredDates =
} dates | ranges::views::filter([this](const auto& date)
{ return !archiveMap_.contains(date); });
lock.unlock(); lock.unlock();
logger_->debug("Load Archive: {}, {}", util::TimeString(date), pil);
// Query for products // Query for products
const auto& productIds = iemApiProvider_->ListTextProducts(date, {}, pil); const auto& productIds =
iemApiProvider_->ListTextProducts(filteredDates, {}, kPils_);
if (productIds.has_value()) if (productIds.has_value())
{ {
logger_->debug("Loading {} {} products", productIds.value().size(), pil); logger_->debug("Loading {} products", productIds.value().size());
// Load listed products // Load listed products
auto products = iemApiProvider_->LoadTextProducts(productIds.value()); auto products = iemApiProvider_->LoadTextProducts(productIds.value());
@ -338,30 +338,17 @@ void TextEventManager::Impl::LoadArchive(std::chrono::sys_days date,
lock.lock(); lock.lock();
// Ensure the archive map still contains the date, and has not been pruned for (const auto& date : dates)
if (archiveMap_.contains(date))
{ {
// Store the products associated with the PIL in the archive archiveMap_[date];
dateArchive.try_emplace(pil, std::move(products));
// TODO: Store the products in the archive
} }
lock.unlock(); lock.unlock();
} }
} }
void TextEventManager::Impl::LoadArchives(std::chrono::sys_days date)
{
logger_->trace("Load Archives: {}", util::TimeString(date));
UpdateArchiveDates(date);
for (auto& pil : kPils_)
{
boost::asio::post(threadPool_,
[this, date, &pil]() { LoadArchive(date, pil); });
}
}
void TextEventManager::Impl::RefreshAsync() void TextEventManager::Impl::RefreshAsync()
{ {
boost::asio::post(threadPool_, boost::asio::post(threadPool_,
@ -445,14 +432,18 @@ void TextEventManager::Impl::Refresh()
}); });
} }
void TextEventManager::Impl::UpdateArchiveDates(std::chrono::sys_days date) void TextEventManager::Impl::UpdateArchiveDates(
ranges::any_view<std::chrono::sys_days> dates)
{ {
std::unique_lock lock {archiveMutex_}; std::unique_lock lock {archiveMutex_};
for (const auto& date : dates)
{
// Remove any existing occurrences of day, and add to the back of the list // Remove any existing occurrences of day, and add to the back of the list
archiveDates_.remove(date); archiveDates_.remove(date);
archiveDates_.push_back(date); archiveDates_.push_back(date);
} }
}
std::shared_ptr<TextEventManager> TextEventManager::Instance() std::shared_ptr<TextEventManager> TextEventManager::Instance()
{ {