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 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);
extern int hktask_remove(const char *name);
extern void hkshow_tasks(DCB *pdcb);
/**
* @brief Add a new task
*
* 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

View File

@ -11,34 +11,29 @@
* Public License.
*/
#include <maxscale/housekeeper.h>
#include <stdlib.h>
#include <string.h>
#include <maxscale/alloc.h>
#include <maxscale/atomic.h>
#include <maxscale/config.h>
#include <maxscale/semaphore.h>
#include <maxscale/spinlock.h>
#include <maxscale/thread.h>
#include <maxscale/json_api.h>
/**
* @file housekeeper.c Provide a mechanism to run periodic tasks
*
* 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
* shot task that will only be run once after a specified number of
* seconds.
*
* The housekeeper also maintains a global variable, hkheartbeat, that
* 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 *);
bool
hkinit()
bool hkinit()
{
bool inited = false;
@ -74,25 +68,7 @@ hkinit()
return inited;
}
/**
* 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)
int hktask_add(const char *name, void (*taskfn)(void *), void *data, int frequency)
{
HKTASK *task, *ptr;
@ -144,21 +120,7 @@ hktask_add(const char *name, void (*taskfn)(void *), void *data, int frequency)
return task->nextdue;
}
/**
* 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)
int hktask_oneshot(const char *name, void (*taskfn)(void *), void *data, int when)
{
HKTASK *task, *ptr;
@ -196,15 +158,7 @@ hktask_oneshot(const char *name, void (*taskfn)(void *), void *data, int when)
return task->nextdue;
}
/**
* 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)
int hktask_remove(const char *name)
{
HKTASK *ptr, *lptr = NULL;
@ -237,7 +191,6 @@ hktask_remove(const char *name)
}
}
/**
* The housekeeper thread implementation.
*
@ -253,8 +206,7 @@ hktask_remove(const char *name)
*
* @param data Unused, here to satisfy the thread system
*/
void
hkthread(void *data)
void hkthread(void *data)
{
HKTASK *ptr;
time_t now;
@ -304,8 +256,7 @@ hkthread(void *data)
MXS_NOTICE("Housekeeper shutting down.");
}
void
hkshutdown()
void hkshutdown()
{
do_shutdown = true;
atomic_synchronize();
@ -321,13 +272,7 @@ void hkfinish()
MXS_NOTICE("Housekeeper has shut down.");
}
/**
* Show the tasks that are scheduled for the house keeper
*
* @param pdcb The DCB to send to output
*/
void
hkshow_tasks(DCB *pdcb)
void hkshow_tasks(DCB *pdcb)
{
HKTASK *ptr;
struct tm tm;
@ -350,3 +295,40 @@ hkshow_tasks(DCB *pdcb)
}
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/spinlock.hh>
#include <maxscale/json_api.h>
#include <maxscale/housekeeper.h>
#include "maxscale/httprequest.hh"
#include "maxscale/httpresponse.hh"
@ -467,8 +468,7 @@ HttpResponse cb_thread(const HttpRequest& request)
HttpResponse cb_tasks(const HttpRequest& request)
{
// TODO: Show housekeeper tasks
return HttpResponse(MHD_HTTP_OK, mxs_json_resource(request.host(), MXS_JSON_API_TASKS, json_null()));
return HttpResponse(MHD_HTTP_OK, hk_tasks_json(request.host()));
}
HttpResponse cb_all_modules(const HttpRequest& request)