mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 16:40:05 +00:00
Fix crash when switching radar sites while loading data from the old site
- Use thread pools owned by radar product manager, unless called statically (#51)
This commit is contained in:
parent
16e3d1533f
commit
081b626855
1 changed files with 78 additions and 51 deletions
|
|
@ -19,7 +19,9 @@
|
|||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/asio/thread_pool.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/range/irange.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
|
|
@ -91,7 +93,7 @@ public:
|
|||
group_ {group},
|
||||
product_ {product},
|
||||
refreshEnabled_ {false},
|
||||
refreshTimer_ {scwx::util::io_context()},
|
||||
refreshTimer_ {threadPool_},
|
||||
refreshTimerMutex_ {},
|
||||
provider_ {nullptr}
|
||||
{
|
||||
|
|
@ -106,6 +108,8 @@ public:
|
|||
|
||||
void Disable();
|
||||
|
||||
boost::asio::thread_pool threadPool_ {1u};
|
||||
|
||||
const std::string radarId_;
|
||||
const common::RadarProductGroup group_;
|
||||
const std::string product_;
|
||||
|
|
@ -179,6 +183,8 @@ public:
|
|||
|
||||
RadarProductManager* self_;
|
||||
|
||||
boost::asio::thread_pool threadPool_ {4u};
|
||||
|
||||
std::shared_ptr<ProviderManager>
|
||||
GetLevel3ProviderManager(const std::string& product);
|
||||
|
||||
|
|
@ -199,6 +205,10 @@ public:
|
|||
void UpdateRecentRecords(RadarProductRecordList& recentList,
|
||||
std::shared_ptr<types::RadarProductRecord> record);
|
||||
|
||||
void LoadNexradFileAsync(CreateNexradFileFunction load,
|
||||
std::shared_ptr<request::NexradFileRequest> request,
|
||||
std::mutex& mutex,
|
||||
std::chrono::system_clock::time_point time);
|
||||
void LoadProviderData(std::chrono::system_clock::time_point time,
|
||||
std::shared_ptr<ProviderManager> providerManager,
|
||||
RadarProductRecordMap& recordMap,
|
||||
|
|
@ -523,7 +533,8 @@ void RadarProductManager::EnableRefresh(common::RadarProductGroup group,
|
|||
p->GetLevel3ProviderManager(product);
|
||||
|
||||
// Only enable refresh on available products
|
||||
scwx::util::async(
|
||||
boost::asio::post(
|
||||
p->threadPool_,
|
||||
[=, this]()
|
||||
{
|
||||
providerManager->provider_->RequestAvailableProducts();
|
||||
|
|
@ -614,7 +625,8 @@ void RadarProductManagerImpl::RefreshData(
|
|||
providerManager->refreshTimer_.cancel();
|
||||
}
|
||||
|
||||
scwx::util::async(
|
||||
boost::asio::post(
|
||||
threadPool_,
|
||||
[=, this]()
|
||||
{
|
||||
auto [newObjects, totalObjects] =
|
||||
|
|
@ -774,9 +786,8 @@ void RadarProductManagerImpl::LoadProviderData(
|
|||
providerManager->name(),
|
||||
scwx::util::TimeString(time));
|
||||
|
||||
RadarProductManagerImpl::LoadNexradFile(
|
||||
[=, &recordMap, &recordMutex, &loadDataMutex]()
|
||||
-> std::shared_ptr<wsr88d::NexradFile>
|
||||
LoadNexradFileAsync(
|
||||
[=, &recordMap, &recordMutex]() -> std::shared_ptr<wsr88d::NexradFile>
|
||||
{
|
||||
std::shared_ptr<types::RadarProductRecord> existingRecord = nullptr;
|
||||
std::shared_ptr<wsr88d::NexradFile> nexradFile = nullptr;
|
||||
|
|
@ -874,11 +885,15 @@ void RadarProductManager::LoadData(
|
|||
{
|
||||
logger_->debug("LoadData()");
|
||||
|
||||
RadarProductManagerImpl::LoadNexradFile(
|
||||
[=, &is]() -> std::shared_ptr<wsr88d::NexradFile>
|
||||
{ return wsr88d::NexradFileFactory::Create(is); },
|
||||
request,
|
||||
fileLoadMutex_);
|
||||
scwx::util::async(
|
||||
[=, &is]()
|
||||
{
|
||||
RadarProductManagerImpl::LoadNexradFile(
|
||||
[=, &is]() -> std::shared_ptr<wsr88d::NexradFile>
|
||||
{ return wsr88d::NexradFileFactory::Create(is); },
|
||||
request,
|
||||
fileLoadMutex_);
|
||||
});
|
||||
}
|
||||
|
||||
void RadarProductManager::LoadFile(
|
||||
|
|
@ -915,11 +930,15 @@ void RadarProductManager::LoadFile(
|
|||
}
|
||||
});
|
||||
|
||||
RadarProductManagerImpl::LoadNexradFile(
|
||||
[=]() -> std::shared_ptr<wsr88d::NexradFile>
|
||||
{ return wsr88d::NexradFileFactory::Create(filename); },
|
||||
request,
|
||||
fileLoadMutex_);
|
||||
scwx::util::async(
|
||||
[=]()
|
||||
{
|
||||
RadarProductManagerImpl::LoadNexradFile(
|
||||
[=]() -> std::shared_ptr<wsr88d::NexradFile>
|
||||
{ return wsr88d::NexradFileFactory::Create(filename); },
|
||||
request,
|
||||
fileLoadMutex_);
|
||||
});
|
||||
}
|
||||
else if (request != nullptr)
|
||||
{
|
||||
|
|
@ -928,51 +947,58 @@ void RadarProductManager::LoadFile(
|
|||
}
|
||||
}
|
||||
|
||||
void RadarProductManagerImpl::LoadNexradFileAsync(
|
||||
CreateNexradFileFunction load,
|
||||
std::shared_ptr<request::NexradFileRequest> request,
|
||||
std::mutex& mutex,
|
||||
std::chrono::system_clock::time_point time)
|
||||
{
|
||||
boost::asio::post(threadPool_,
|
||||
[=, &mutex]()
|
||||
{ LoadNexradFile(load, request, mutex, time); });
|
||||
}
|
||||
|
||||
void RadarProductManagerImpl::LoadNexradFile(
|
||||
CreateNexradFileFunction load,
|
||||
std::shared_ptr<request::NexradFileRequest> request,
|
||||
std::mutex& mutex,
|
||||
std::chrono::system_clock::time_point time)
|
||||
{
|
||||
scwx::util::async(
|
||||
[=, &mutex]()
|
||||
std::unique_lock lock {mutex};
|
||||
|
||||
std::shared_ptr<wsr88d::NexradFile> nexradFile = load();
|
||||
|
||||
std::shared_ptr<types::RadarProductRecord> record = nullptr;
|
||||
|
||||
bool fileValid = (nexradFile != nullptr);
|
||||
|
||||
if (fileValid)
|
||||
{
|
||||
record = types::RadarProductRecord::Create(nexradFile);
|
||||
|
||||
// If the time is already determined, override the time in the file.
|
||||
// Sometimes, level 2 data has been seen to be a few seconds off
|
||||
// between filename and file data. Overriding this can help prevent
|
||||
// issues with locating and storing the correct records.
|
||||
if (time != std::chrono::system_clock::time_point {})
|
||||
{
|
||||
std::unique_lock lock {mutex};
|
||||
record->set_time(time);
|
||||
}
|
||||
|
||||
std::shared_ptr<wsr88d::NexradFile> nexradFile = load();
|
||||
std::shared_ptr<RadarProductManager> manager =
|
||||
RadarProductManager::Instance(record->radar_id());
|
||||
|
||||
std::shared_ptr<types::RadarProductRecord> record = nullptr;
|
||||
manager->Initialize();
|
||||
record = manager->p->StoreRadarProductRecord(record);
|
||||
}
|
||||
|
||||
bool fileValid = (nexradFile != nullptr);
|
||||
lock.unlock();
|
||||
|
||||
if (fileValid)
|
||||
{
|
||||
record = types::RadarProductRecord::Create(nexradFile);
|
||||
|
||||
// If the time is already determined, override the time in the file.
|
||||
// Sometimes, level 2 data has been seen to be a few seconds off
|
||||
// between filename and file data. Overriding this can help prevent
|
||||
// issues with locating and storing the correct records.
|
||||
if (time != std::chrono::system_clock::time_point {})
|
||||
{
|
||||
record->set_time(time);
|
||||
}
|
||||
|
||||
std::shared_ptr<RadarProductManager> manager =
|
||||
RadarProductManager::Instance(record->radar_id());
|
||||
|
||||
manager->Initialize();
|
||||
record = manager->p->StoreRadarProductRecord(record);
|
||||
}
|
||||
|
||||
lock.unlock();
|
||||
|
||||
if (request != nullptr)
|
||||
{
|
||||
request->set_radar_product_record(record);
|
||||
Q_EMIT request->RequestComplete(request);
|
||||
}
|
||||
});
|
||||
if (request != nullptr)
|
||||
{
|
||||
request->set_radar_product_record(record);
|
||||
Q_EMIT request->RequestComplete(request);
|
||||
}
|
||||
}
|
||||
|
||||
void RadarProductManagerImpl::PopulateLevel2ProductTimes(
|
||||
|
|
@ -1349,7 +1375,8 @@ void RadarProductManager::UpdateAvailableProducts()
|
|||
|
||||
logger_->debug("UpdateAvailableProducts()");
|
||||
|
||||
scwx::util::async(
|
||||
boost::asio::post(
|
||||
p->threadPool_,
|
||||
[this]()
|
||||
{
|
||||
auto level3ProviderManager =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue