From d6f22132cee951e4229cee93389ed548b6bc68e6 Mon Sep 17 00:00:00 2001 From: HiepLM Date: Sat, 13 Jun 2026 13:49:42 +0700 Subject: [PATCH] =?UTF-8?q?Test=20l=E1=BA=A7n=201=20oke?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mission/mission_queue.cpp | 129 +++++++++++------- src/mission/mission_queue.hpp | 6 +- ...pi_integration.cpython-38-pytest-8.3.5.pyc | Bin 0 -> 9563 bytes 3 files changed, 83 insertions(+), 52 deletions(-) create mode 100644 tests/__pycache__/test_api_integration.cpython-38-pytest-8.3.5.pyc diff --git a/src/mission/mission_queue.cpp b/src/mission/mission_queue.cpp index 740a763..3d09591 100644 --- a/src/mission/mission_queue.cpp +++ b/src/mission/mission_queue.cpp @@ -52,7 +52,7 @@ MissionQueue::~MissionQueue() void MissionQueue::load() { - std::lock_guard lock(mu_); + std::lock_guard lock(mu_); queue_ = nlohmann::json::array(); runner_ = nlohmann::json::object(); if (!std::filesystem::exists(queue_path_)) @@ -97,6 +97,12 @@ void MissionQueue::ensureRunnerDefaults() runner_["paused"] = false; } +void MissionQueue::saveLocked() const +{ + std::lock_guard lock(mu_); + saveUnlocked(); +} + void MissionQueue::startWorkerIfNeeded() { if (worker_.joinable()) @@ -106,13 +112,13 @@ void MissionQueue::startWorkerIfNeeded() nlohmann::json MissionQueue::list() const { - std::lock_guard lock(mu_); + std::lock_guard lock(mu_); return queue_; } nlohmann::json MissionQueue::runnerStatus() const { - std::lock_guard lock(mu_); + std::lock_guard lock(mu_); return runner_; } @@ -147,7 +153,7 @@ std::optional MissionQueue::enqueue(const nlohmann::json& payloa entry["log"] = nlohmann::json::array(); { - std::lock_guard lock(mu_); + std::lock_guard lock(mu_); insertByPriorityUnlocked(entry); saveUnlocked(); } @@ -181,7 +187,7 @@ void MissionQueue::insertByPriorityUnlocked(nlohmann::json& entry) bool MissionQueue::removeById(const std::string& id, std::string& err) { - std::lock_guard lock(mu_); + std::lock_guard lock(mu_); if (!queue_.is_array()) { err = "queue unavailable"; @@ -218,7 +224,7 @@ bool MissionQueue::removeById(const std::string& id, std::string& err) bool MissionQueue::clearAll(std::string& err) { (void)err; - std::lock_guard lock(mu_); + std::lock_guard lock(mu_); nlohmann::json next = nlohmann::json::array(); for (const auto& item : queue_) { @@ -241,7 +247,7 @@ bool MissionQueue::reorder(const nlohmann::json& ordered_ids, std::string& err) return false; } - std::lock_guard lock(mu_); + std::lock_guard lock(mu_); if (!queue_.is_array()) { err = "queue unavailable"; @@ -285,7 +291,7 @@ bool MissionQueue::reorder(const nlohmann::json& ordered_ids, std::string& err) bool MissionQueue::pause(std::string& err) { - std::lock_guard lock(mu_); + std::lock_guard lock(mu_); const std::string state = runner_.value("state", "idle"); if (state != "running") { @@ -306,7 +312,7 @@ bool MissionQueue::resume(std::string& err) (void)err; paused_ = false; { - std::lock_guard lock(mu_); + std::lock_guard lock(mu_); runner_["paused"] = false; if (runner_.value("state", "") == "paused") { @@ -324,46 +330,65 @@ void MissionQueue::workerLoop() { while (!stop_) { + nlohmann::json working; + bool run = false; { - std::lock_guard lock(mu_); - processQueueUnlocked(); + std::lock_guard lock(mu_); + if (!paused_ && queue_.is_array()) + { + for (auto& item : queue_) + { + if (!item.is_object()) + continue; + if (item.value("status", "") != "pending") + continue; + item["status"] = "executing"; + item["started_at"] = IdUtil::nowIso8601(); + runner_["current_queue_id"] = item.value("id", ""); + runner_["current_action"] = nullptr; + setRunnerState("running", "Đang chạy: " + item.value("mission_name", "Mission")); + saveUnlocked(); + working = item; + run = true; + break; + } + } + if (!run && runner_.value("state", "") == "running") + { + setRunnerState("idle", "Queue trống"); + saveUnlocked(); + } } + + if (run) + { + runMissionActions(working); + { + std::lock_guard lock(mu_); + const std::string id = working.value("id", ""); + for (auto& item : queue_) + { + if (item.is_object() && item.value("id", "") == id) + { + item = working; + break; + } + } + runner_["current_queue_id"] = nullptr; + runner_["current_action"] = nullptr; + saveUnlocked(); + } + wake_ = true; + } + for (int i = 0; i < 20 && !wake_; ++i) std::this_thread::sleep_for(std::chrono::milliseconds(100)); wake_ = false; } } -void MissionQueue::processQueueUnlocked() +void MissionQueue::runMissionActions(nlohmann::json& entry) { - if (!queue_.is_array()) - return; - if (paused_) - return; - - for (auto& item : queue_) - { - if (!item.is_object()) - continue; - if (item.value("status", "") != "pending") - continue; - executeMissionUnlocked(item); - return; - } - - if (runner_.value("state", "") == "running") - setRunnerState("idle", "Queue trống"); -} - -void MissionQueue::executeMissionUnlocked(nlohmann::json& entry) -{ - entry["status"] = "executing"; - entry["started_at"] = IdUtil::nowIso8601(); - runner_["current_queue_id"] = entry.value("id", ""); - runner_["current_action"] = nullptr; - setRunnerState("running", "Đang chạy: " + entry.value("mission_name", "Mission")); - saveUnlocked(); - try { nlohmann::json log = nlohmann::json::array(); @@ -375,19 +400,22 @@ void MissionQueue::executeMissionUnlocked(nlohmann::json& entry) entry["log"] = log; entry["status"] = "completed"; entry["finished_at"] = IdUtil::nowIso8601(); - setRunnerState("idle", "Hoàn thành: " + entry.value("mission_name", "Mission")); + { + std::lock_guard lock(mu_); + setRunnerState("idle", "Hoàn thành: " + entry.value("mission_name", "Mission")); + saveUnlocked(); + } } catch (...) { entry["status"] = "failed"; entry["finished_at"] = IdUtil::nowIso8601(); - setRunnerState("error", "Lỗi khi chạy: " + entry.value("mission_name", "Mission")); + { + std::lock_guard lock(mu_); + setRunnerState("error", "Lỗi khi chạy: " + entry.value("mission_name", "Mission")); + saveUnlocked(); + } } - - runner_["current_queue_id"] = nullptr; - runner_["current_action"] = nullptr; - saveUnlocked(); - wake_ = true; } void MissionQueue::executeActionsUnlocked(const nlohmann::json& actions, @@ -414,8 +442,11 @@ void MissionQueue::executeActionsUnlocked(const nlohmann::json& actions, const auto& params = action.contains("params") && action["params"].is_object() ? action["params"] : nlohmann::json::object(); - runner_["current_action"] = label; - saveUnlocked(); + { + std::lock_guard lock(mu_); + runner_["current_action"] = label; + saveUnlocked(); + } if (kind == "mission") { diff --git a/src/mission/mission_queue.hpp b/src/mission/mission_queue.hpp index e419949..79c74ba 100644 --- a/src/mission/mission_queue.hpp +++ b/src/mission/mission_queue.hpp @@ -32,7 +32,7 @@ public: private: std::filesystem::path queue_path_; - mutable std::mutex mu_; + mutable std::recursive_mutex mu_; nlohmann::json queue_; nlohmann::json runner_; @@ -46,12 +46,12 @@ private: void ensureRunnerDefaults(); void startWorkerIfNeeded(); void workerLoop(); - void processQueueUnlocked(); - void executeMissionUnlocked(nlohmann::json& entry); + void runMissionActions(nlohmann::json& entry); void executeActionsUnlocked(const nlohmann::json& actions, const nlohmann::json& parameters, nlohmann::json& log, int loop_depth); + void saveLocked() const; void sleepMs(int ms); void setRunnerState(const std::string& state, const std::string& message = ""); void insertByPriorityUnlocked(nlohmann::json& entry); diff --git a/tests/__pycache__/test_api_integration.cpython-38-pytest-8.3.5.pyc b/tests/__pycache__/test_api_integration.cpython-38-pytest-8.3.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03f025dcdc2b57cd5576815e2cda17647fbe5983 GIT binary patch literal 9563 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 aYdA&)ew$^wx;yRIPTrYz7M(d~_J05}eclQH literal 0 HcmV?d00001