MXS-1220: Add /maxscale/tasks resource

The resource shows all active tasks inside MaxScale.
This commit is contained in:
Markus Mäkelä
2017-05-09 08:50:26 +03:00
parent 613b924f2e
commit 9fee283a3f
3 changed files with 107 additions and 73 deletions

View File

@ -68,9 +68,61 @@ extern void hkshutdown();
*/ */
extern void hkfinish(); extern void hkfinish();
extern int hktask_add(const char *name, void (*task)(void *), void *data, int frequency); /**
extern int hktask_oneshot(const char *name, void (*task)(void *), void *data, int when); * @brief Add a new task
extern int hktask_remove(const char *name); *
extern void hkshow_tasks(DCB *pdcb); * The task will be first run @c frequency seconds after this call is
* made and will the be executed repeatedly every frequency seconds
* until the task is removed.
*
* Task names must be unique.
*
* @param name Task name
* @param task Function to execute
* @param data Data passed to function as the parameter
* @param frequency Frequency of execution
*
* @return 1 if task was added
*/
int hktask_add(const char *name, void (*task)(void *) , void *data, int frequency);
/**
* @brief Add oneshot task
*
* The task will only execute once.
*
* @param name Task name
* @param task Function to execute
* @param data Data passed to function as the parameter
* @param when Number of seconds to wait until task is executed
*
* @return 1 if task was added
*/
int hktask_oneshot(const char *name, void (*task)(void *) , void *data, int when);
/**
* @brief Remove a task
*
* @param name Task name
*
* @return 1 if the task was removed
*/
int hktask_remove(const char *name);
/**
* @brief Show the tasks that are scheduled for the house keeper
*
* @param pdcb The DCB to send to output
*/
void hkshow_tasks(DCB *pdcb);
/**
* @brief Show tasks as JSON resource
*
* @param host Hostname of this server
*
* @return Collection of JSON formatted task resources
*/
json_t* hk_tasks_json(const char* host);
MXS_END_DECLS MXS_END_DECLS

View File

@ -11,34 +11,29 @@
* Public License. * Public License.
*/ */
#include <maxscale/housekeeper.h> #include <maxscale/housekeeper.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <maxscale/alloc.h> #include <maxscale/alloc.h>
#include <maxscale/atomic.h> #include <maxscale/atomic.h>
#include <maxscale/config.h>
#include <maxscale/semaphore.h> #include <maxscale/semaphore.h>
#include <maxscale/spinlock.h> #include <maxscale/spinlock.h>
#include <maxscale/thread.h> #include <maxscale/thread.h>
#include <maxscale/json_api.h>
/** /**
* @file housekeeper.c Provide a mechanism to run periodic tasks * @file housekeeper.c Provide a mechanism to run periodic tasks
* *
* The housekeeper provides a mechanism to allow for tasks, function * The housekeeper provides a mechanism to allow for tasks, function
* calls basically, to be run on a tiem basis. A task may be run * calls basically, to be run on a time basis. A task may be run
* repeatedly, with a given frequency (in seconds), or may be a one * repeatedly, with a given frequency (in seconds), or may be a one
* shot task that will only be run once after a specified number of * shot task that will only be run once after a specified number of
* seconds. * seconds.
* *
* The housekeeper also maintains a global variable, hkheartbeat, that * The housekeeper also maintains a global variable, hkheartbeat, that
* is incremented every 100ms. * is incremented every 100ms.
*
* @verbatim
* Revision History
*
* Date Who Description
* 29/08/14 Mark Riddoch Initial implementation
* 22/10/14 Mark Riddoch Addition of one-shot tasks
*
* @endverbatim
*/ */
/** /**
@ -57,8 +52,7 @@ static THREAD hk_thr_handle;
static void hkthread(void *); static void hkthread(void *);
bool bool hkinit()
hkinit()
{ {
bool inited = false; bool inited = false;
@ -74,25 +68,7 @@ hkinit()
return inited; return inited;
} }
/** int hktask_add(const char *name, void (*taskfn)(void *), void *data, int frequency)
* Add a new task to the housekeepers lists of tasks that should be
* run periodically.
*
* The task will be first run frequency seconds after this call is
* made and will the be executed repeatedly every frequency seconds
* until the task is removed.
*
* Task names must be unique.
*
* @param name The unique name for this housekeeper task
* @param taskfn The function to call for the task
* @param data Data to pass to the task function
* @param frequency How often to run the task, expressed in seconds
* @return Return the time in seconds when the task will be first run
* if the task was added, otherwise 0
*/
int
hktask_add(const char *name, void (*taskfn)(void *), void *data, int frequency)
{ {
HKTASK *task, *ptr; HKTASK *task, *ptr;
@ -144,21 +120,7 @@ hktask_add(const char *name, void (*taskfn)(void *), void *data, int frequency)
return task->nextdue; return task->nextdue;
} }
/** int hktask_oneshot(const char *name, void (*taskfn)(void *), void *data, int when)
* Add a one-shot task to the housekeeper task list
*
* Task names must be unique.
*
* @param name The unique name for this housekeeper task
* @param taskfn The function to call for the task
* @param data Data to pass to the task function
* @param when How many second until the task is executed
* @return Return the time in seconds when the task will be first run
* if the task was added, otherwise 0
*
*/
int
hktask_oneshot(const char *name, void (*taskfn)(void *), void *data, int when)
{ {
HKTASK *task, *ptr; HKTASK *task, *ptr;
@ -196,15 +158,7 @@ hktask_oneshot(const char *name, void (*taskfn)(void *), void *data, int when)
return task->nextdue; return task->nextdue;
} }
int hktask_remove(const char *name)
/**
* Remove a named task from the housekeepers task list
*
* @param name The task name to remove
* @return Returns 0 if the task could not be removed
*/
int
hktask_remove(const char *name)
{ {
HKTASK *ptr, *lptr = NULL; HKTASK *ptr, *lptr = NULL;
@ -237,7 +191,6 @@ hktask_remove(const char *name)
} }
} }
/** /**
* The housekeeper thread implementation. * The housekeeper thread implementation.
* *
@ -253,8 +206,7 @@ hktask_remove(const char *name)
* *
* @param data Unused, here to satisfy the thread system * @param data Unused, here to satisfy the thread system
*/ */
void void hkthread(void *data)
hkthread(void *data)
{ {
HKTASK *ptr; HKTASK *ptr;
time_t now; time_t now;
@ -304,8 +256,7 @@ hkthread(void *data)
MXS_NOTICE("Housekeeper shutting down."); MXS_NOTICE("Housekeeper shutting down.");
} }
void void hkshutdown()
hkshutdown()
{ {
do_shutdown = true; do_shutdown = true;
atomic_synchronize(); atomic_synchronize();
@ -321,13 +272,7 @@ void hkfinish()
MXS_NOTICE("Housekeeper has shut down."); MXS_NOTICE("Housekeeper has shut down.");
} }
/** void hkshow_tasks(DCB *pdcb)
* Show the tasks that are scheduled for the house keeper
*
* @param pdcb The DCB to send to output
*/
void
hkshow_tasks(DCB *pdcb)
{ {
HKTASK *ptr; HKTASK *ptr;
struct tm tm; struct tm tm;
@ -350,3 +295,40 @@ hkshow_tasks(DCB *pdcb)
} }
spinlock_release(&tasklock); spinlock_release(&tasklock);
} }
json_t* hk_tasks_json(const char* host)
{
json_t* arr = json_array();
spinlock_acquire(&tasklock);
for (HKTASK* ptr = tasks; ptr; ptr = ptr->next)
{
struct tm tm;
char buf[40];
localtime_r(&ptr->nextdue, &tm);
asctime_r(&tm, buf);
char* nl = strchr(buf, '\n');
ss_dassert(nl);
*nl = '\0';
const char* task_type = ptr->type == HK_REPEATED ? "Repeated" : "One-Shot";
json_t* obj = json_object();
json_object_set_new(obj, CN_ID, json_string(ptr->name));
json_object_set_new(obj, CN_TYPE, json_string("tasks"));
json_t* attr = json_object();
json_object_set_new(attr, "task_type", json_string(task_type));
json_object_set_new(attr, "frequency", json_integer(ptr->frequency));
json_object_set_new(attr, "next_execution", json_string(buf));
json_object_set_new(obj, CN_ATTRIBUTES, attr);
json_array_append_new(arr, obj);
}
spinlock_release(&tasklock);
return mxs_json_resource(host, MXS_JSON_API_TASKS, arr);
}

View File

@ -20,6 +20,7 @@
#include <maxscale/jansson.hh> #include <maxscale/jansson.hh>
#include <maxscale/spinlock.hh> #include <maxscale/spinlock.hh>
#include <maxscale/json_api.h> #include <maxscale/json_api.h>
#include <maxscale/housekeeper.h>
#include "maxscale/httprequest.hh" #include "maxscale/httprequest.hh"
#include "maxscale/httpresponse.hh" #include "maxscale/httpresponse.hh"
@ -467,8 +468,7 @@ HttpResponse cb_thread(const HttpRequest& request)
HttpResponse cb_tasks(const HttpRequest& request) HttpResponse cb_tasks(const HttpRequest& request)
{ {
// TODO: Show housekeeper tasks return HttpResponse(MHD_HTTP_OK, hk_tasks_json(request.host()));
return HttpResponse(MHD_HTTP_OK, mxs_json_resource(request.host(), MXS_JSON_API_TASKS, json_null()));
} }
HttpResponse cb_all_modules(const HttpRequest& request) HttpResponse cb_all_modules(const HttpRequest& request)