fix deadlock, remove pending tasks if the contain state == "success" in result JSON, check every second

This commit is contained in:
einhornimmond 2021-03-03 14:49:17 +01:00 committed by Ulf Gebhardt
parent c1e82dda94
commit 82f39c3add
No known key found for this signature in database
GPG Key ID: 81308EFE29ABFEBD
3 changed files with 55 additions and 13 deletions

View File

@ -4,13 +4,17 @@
PendingTasksManager::PendingTasksManager() PendingTasksManager::PendingTasksManager()
: mCheckForFinishedTimer(2000, 2000)
{ {
//mCheckForFinishedTimer
} }
PendingTasksManager::~PendingTasksManager() PendingTasksManager::~PendingTasksManager()
{ {
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex); Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
mCheckForFinishedTimer.stop();
for (auto it = mPendingTasks.begin(); it != mPendingTasks.end(); it++) { for (auto it = mPendingTasks.begin(); it != mPendingTasks.end(); it++) {
delete it->second; delete it->second;
} }
@ -27,6 +31,9 @@ int PendingTasksManager::load()
{ {
// they add them self to Pending Task Manager // they add them self to Pending Task Manager
auto pending_tasks = controller::PendingTask::loadAll(); auto pending_tasks = controller::PendingTask::loadAll();
Poco::TimerCallback<PendingTasksManager> callback(*this, &PendingTasksManager::checkForFinishedTasks);
mCheckForFinishedTimer.start(callback);
return 0; return 0;
} }
@ -138,9 +145,11 @@ std::vector<Poco::AutoPtr<controller::PendingTask>> PendingTasksManager::getTra
auto list = map_it->second; auto list = map_it->second;
for (auto list_it = list->begin(); list_it != list->end(); list_it++) for (auto list_it = list->begin(); list_it != list->end(); list_it++)
{ {
auto transaction = dynamic_cast<model::gradido::Transaction*>(list_it->get()); if ((*list_it)->getModel()->isGradidoTransaction()) {
if (transaction->mustSign(user)) { auto transaction = dynamic_cast<model::gradido::Transaction*>(list_it->get());
transactions_to_sign.push_back(*list_it); if (transaction->mustSign(user)) {
transactions_to_sign.push_back(*list_it);
}
} }
} }
} }
@ -158,15 +167,45 @@ std::vector<Poco::AutoPtr<controller::PendingTask>> PendingTasksManager::getTran
auto list = map_it->second; auto list = map_it->second;
for (auto list_it = list->begin(); list_it != list->end(); list_it++) for (auto list_it = list->begin(); list_it != list->end(); list_it++)
{ {
auto transaction = dynamic_cast<model::gradido::Transaction*>(list_it->get()); if ((*list_it)->getModel()->isGradidoTransaction()) {
if (transaction->needSomeoneToSign(user)) { auto transaction = dynamic_cast<model::gradido::Transaction*>(list_it->get());
transactions_to_sign.push_back(*list_it); if (transaction->needSomeoneToSign(user)) {
transactions_to_sign.push_back(*list_it);
}
} }
} }
} }
return transactions_to_sign; return transactions_to_sign;
} }
void PendingTasksManager::checkForFinishedTasks(Poco::Timer& timer)
{
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
for (auto map_it = mPendingTasks.begin(); map_it != mPendingTasks.end(); map_it++)
{
auto list = map_it->second;
for (auto list_it = list->begin(); list_it != list->end(); list_it++)
{
if ((*list_it)->getModel()->isGradidoTransaction()) {
auto transaction = dynamic_cast<model::gradido::Transaction*>(list_it->get());
auto json = transaction->getModel()->getResultJson();
bool removeIt = false;
if (!json.isNull()) {
if (json->get("state").toString() == "success") {
removeIt = true;
}
}
if (removeIt) {
transaction->deleteFromDB();
list_it = list->erase(list_it);
if (!list->size()) break;
}
}
}
}
}
Poco::AutoPtr<controller::PendingTask> PendingTasksManager::getPendingTask(int pendingTaskId) Poco::AutoPtr<controller::PendingTask> PendingTasksManager::getPendingTask(int pendingTaskId)
{ {
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex); Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
@ -183,6 +222,7 @@ Poco::AutoPtr<controller::PendingTask> PendingTasksManager::getPendingTask(int p
return nullptr; return nullptr;
} }
void PendingTasksManager::reportErrorToCommunityServer(Poco::AutoPtr<controller::PendingTask> task, std::string error, std::string errorDetails) void PendingTasksManager::reportErrorToCommunityServer(Poco::AutoPtr<controller::PendingTask> task, std::string error, std::string errorDetails)
{ {
// TODO: choose user specific server // TODO: choose user specific server

View File

@ -17,8 +17,11 @@
#include "../controller/User.h" #include "../controller/User.h"
#include "../model/gradido/Transaction.h" #include "../model/gradido/Transaction.h"
class PendingTasksManager: public UniLib::lib::MultithreadContainer class UserUpdateGroupPage;
class PendingTasksManager: protected UniLib::lib::MultithreadContainer
{ {
friend UserUpdateGroupPage;
public: public:
typedef std::list<Poco::AutoPtr<controller::PendingTask>> PendingTaskList; typedef std::list<Poco::AutoPtr<controller::PendingTask>> PendingTaskList;
@ -34,6 +37,9 @@ public:
int addTask(Poco::AutoPtr<controller::PendingTask> task); int addTask(Poco::AutoPtr<controller::PendingTask> task);
bool removeTask(Poco::AutoPtr<controller::PendingTask> task); bool removeTask(Poco::AutoPtr<controller::PendingTask> task);
//! check if tasks can be removed
void checkForFinishedTasks(Poco::Timer& timer);
//! by calling this, important is to call lock to prevent vanishing the list while working with it, //! by calling this, important is to call lock to prevent vanishing the list while working with it,
//! and unlock afterwards //! and unlock afterwards
//! \return list or nullptr if no list for user exist //! \return list or nullptr if no list for user exist
@ -49,7 +55,7 @@ public:
protected: protected:
PendingTasksManager(); PendingTasksManager();
Poco::Timer mCheckForFinishedTimer;
std::map<int, PendingTaskList*> mPendingTasks; std::map<int, PendingTaskList*> mPendingTasks;

View File

@ -87,10 +87,6 @@ namespace controller {
{ {
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex); Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
auto result = mDBModel->deleteFromDB(); auto result = mDBModel->deleteFromDB();
if (result) {
PendingTasksManager::getInstance()->removeTask(Poco::AutoPtr<PendingTask>(this, true));
}
return result; return result;
} }