From 2d2f62ed6f9ad48a731d36f2f8a996385686e6e3 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 8 Jan 2019 09:18:21 +0200 Subject: [PATCH] MXS-2218 Add showing and to_json functionality --- include/maxscale/mainworker.hh | 9 ++++- server/core/mainworker.cc | 68 +++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/include/maxscale/mainworker.hh b/include/maxscale/mainworker.hh index e864c361f..0781c5fe6 100644 --- a/include/maxscale/mainworker.hh +++ b/include/maxscale/mainworker.hh @@ -45,6 +45,9 @@ public: void add_task(const char* zName, TASKFN func, void* pData, int frequency); void remove_task(const char* zName); + void show_tasks(DCB* pDcb) const; + json_t* tasks_to_json(const char* zhost) const; + private: bool pre_run() override; void post_run() override; @@ -53,10 +56,12 @@ private: struct Task { public: - Task(const char* zName, TASKFN func, void* pData) + Task(const char* zName, TASKFN func, void* pData, int frequency) : name(zName) , func(func) , pData(pData) + , frequency(frequency) + , nextdue(time(0) + frequency) , id(0) { }; @@ -64,6 +69,8 @@ private: std::string name; TASKFN func; void* pData; + int frequency; + time_t nextdue; uint32_t id; }; diff --git a/server/core/mainworker.cc b/server/core/mainworker.cc index 555d808cd..d4c2cc30b 100644 --- a/server/core/mainworker.cc +++ b/server/core/mainworker.cc @@ -13,6 +13,7 @@ #include #include +#include namespace { @@ -54,7 +55,7 @@ void MainWorker::add_task(const char* zName, TASKFN func, void* pData, int frequ call([=]() { mxb_assert(m_tasks_by_name.find(zName) == m_tasks_by_name.end()); - Task task(zName, func, pData); + Task task(zName, func, pData, frequency); auto p = m_tasks_by_name.insert(std::make_pair(std::string(zName), task)); Task& inserted_task = (*p.first).second; @@ -84,6 +85,65 @@ void MainWorker::remove_task(const char* zName) EXECUTE_AUTO); } +void MainWorker::show_tasks(DCB* pDcb) const +{ + // TODO: Make call() const. + MainWorker* pThis = const_cast(this); + pThis->call([this, pDcb] () { + dcb_printf(pDcb, "%-25s | Frequency | Next Due\n", "Name"); + dcb_printf(pDcb, "--------------------------+-----------+-------------------------\n"); + + for (auto it = m_tasks_by_name.begin(); it != m_tasks_by_name.end(); ++it) + { + const Task& task = it->second; + + struct tm tm; + char buf[40]; + localtime_r(&task.nextdue, &tm); + asctime_r(&tm, buf); + dcb_printf(pDcb, "%-25s | %-9d | %s", task.name.c_str(), task.frequency, buf); + } + }, + EXECUTE_AUTO); +} + +json_t* MainWorker::tasks_to_json(const char* zHost) const +{ + json_t* pResult = json_array(); + + // TODO: Make call() const. + MainWorker* pThis = const_cast(this); + pThis->call([this, zHost, pResult]() { + for (auto it = m_tasks_by_name.begin(); it != m_tasks_by_name.end(); ++it) + { + const Task& task = it->second; + + struct tm tm; + char buf[40]; + localtime_r(&task.nextdue, &tm); + asctime_r(&tm, buf); + char* nl = strchr(buf, '\n'); + mxb_assert(nl); + *nl = '\0'; + + json_t* pObject = json_object(); + + json_object_set_new(pObject, CN_ID, json_string(task.name.c_str())); + json_object_set_new(pObject, CN_TYPE, json_string("tasks")); + + json_t* pAttrs = json_object(); + json_object_set_new(pAttrs, "frequency", json_integer(task.frequency)); + json_object_set_new(pAttrs, "next_execution", json_string(buf)); + + json_object_set_new(pObject, CN_ATTRIBUTES, pAttrs); + json_array_append_new(pResult, pObject); + } + }, + EXECUTE_AUTO); + + return pResult; +} + bool MainWorker::pre_run() { return true; @@ -107,7 +167,11 @@ bool MainWorker::call_task(Worker::Call::action_t action, MainWorker::Task* pTas call_again = pTask->func(pTask->pData); - if (!call_again) + if (call_again) + { + pTask->nextdue = time(0) + pTask->frequency; + } + else { auto it = m_tasks_by_name.find(pTask->name);