2020-06-04 03:20:54 -04:00
|
|
|
/*
|
|
|
|
|
* include/haproxy/hlua.h
|
|
|
|
|
* Lua core management functions
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2015-2016 Thierry Fournier <tfournier@arpalert.org>
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation, version 2.1
|
|
|
|
|
* exclusively.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
*/
|
2015-01-23 08:06:13 -05:00
|
|
|
|
2020-06-04 03:20:54 -04:00
|
|
|
#ifndef _HAPROXY_HLUA_H
|
|
|
|
|
#define _HAPROXY_HLUA_H
|
2015-03-04 10:48:34 -05:00
|
|
|
|
2020-06-04 03:20:54 -04:00
|
|
|
#include <haproxy/hlua-t.h>
|
2015-01-23 08:06:13 -05:00
|
|
|
|
2020-06-04 03:20:54 -04:00
|
|
|
#ifdef USE_LUA
|
2015-01-23 08:06:13 -05:00
|
|
|
|
2015-03-03 09:17:35 -05:00
|
|
|
/* The following macros are used to set flags. */
|
|
|
|
|
#define HLUA_SET_RUN(__hlua) do {(__hlua)->flags |= HLUA_RUN;} while(0)
|
|
|
|
|
#define HLUA_CLR_RUN(__hlua) do {(__hlua)->flags &= ~HLUA_RUN;} while(0)
|
|
|
|
|
#define HLUA_IS_RUNNING(__hlua) ((__hlua)->flags & HLUA_RUN)
|
DEBUG: lua: precisely identify if stream is stuck inside lua or not
When ha_panic() is called by the watchdog, we try to guess from
ha_task_dump() and ha_thread_dump_one() if the thread was stuck while
executing lua from the stream context. However we consider this is the
case by simply checking if the stream hlua context was set, but this is
not very precise because if the hlua context is set, then it simply means
that at least one lua instruction was executed at the stream level, not
that the stuck was currently executing lua when the panic occured.
This is especially true with filters, one could simply register a lua
filter that does nothing but this will still end up initializing the
stream hlua context for each stream. If the thread end up being stuck
during the stream handling, then debug dumping functions will report
that the stream was stuck while handling lua, which is not necessarilly
true, and could in fact confuse us even more.
So here we take another approach, we add the BUSY flag to hlua context:
this flag is set by hlua_ctx_resume() around lua_resume() call, this way
we can precisely tell if the thread was handling lua when it was
interrupted, and we rely on this flag in debug functions to check if the
thread was effectively stuck inside lua or not while processing the stream
No backport needed unless a commit depends on it.
2024-03-11 19:22:44 -04:00
|
|
|
#define HLUA_SET_BUSY(__hlua) do {(__hlua)->flags |= HLUA_BUSY;} while(0)
|
|
|
|
|
#define HLUA_CLR_BUSY(__hlua) do {(__hlua)->flags &= ~HLUA_BUSY;} while(0)
|
|
|
|
|
#define HLUA_IS_BUSY(__hlua) ((__hlua)->flags & HLUA_BUSY)
|
2015-03-03 11:29:06 -05:00
|
|
|
#define HLUA_SET_CTRLYIELD(__hlua) do {(__hlua)->flags |= HLUA_CTRLYIELD;} while(0)
|
|
|
|
|
#define HLUA_CLR_CTRLYIELD(__hlua) do {(__hlua)->flags &= ~HLUA_CTRLYIELD;} while(0)
|
|
|
|
|
#define HLUA_IS_CTRLYIELDING(__hlua) ((__hlua)->flags & HLUA_CTRLYIELD)
|
2015-03-05 11:45:34 -05:00
|
|
|
#define HLUA_SET_WAKERESWR(__hlua) do {(__hlua)->flags |= HLUA_WAKERESWR;} while(0)
|
|
|
|
|
#define HLUA_CLR_WAKERESWR(__hlua) do {(__hlua)->flags &= ~HLUA_WAKERESWR;} while(0)
|
|
|
|
|
#define HLUA_IS_WAKERESWR(__hlua) ((__hlua)->flags & HLUA_WAKERESWR)
|
2015-03-05 18:35:53 -05:00
|
|
|
#define HLUA_SET_WAKEREQWR(__hlua) do {(__hlua)->flags |= HLUA_WAKEREQWR;} while(0)
|
|
|
|
|
#define HLUA_CLR_WAKEREQWR(__hlua) do {(__hlua)->flags &= ~HLUA_WAKEREQWR;} while(0)
|
|
|
|
|
#define HLUA_IS_WAKEREQWR(__hlua) ((__hlua)->flags & HLUA_WAKEREQWR)
|
2021-08-04 11:58:21 -04:00
|
|
|
#define HLUA_CLR_NOYIELD(__hlua) do {(__hlua)->flags &= ~HLUA_NOYIELD;} while(0)
|
|
|
|
|
#define HLUA_SET_NOYIELD(__hlua) do {(__hlua)->flags |= HLUA_NOYIELD;} while(0)
|
|
|
|
|
#define HLUA_CANT_YIELD(__hlua) ((__hlua)->flags & HLUA_NOYIELD)
|
|
|
|
|
|
2015-03-03 09:17:35 -05:00
|
|
|
|
2015-03-04 10:48:34 -05:00
|
|
|
#define HLUA_INIT(__hlua) do { (__hlua)->T = 0; } while(0)
|
|
|
|
|
|
2015-01-23 08:06:13 -05:00
|
|
|
/* Lua HAProxy integration functions. */
|
2021-03-24 09:48:45 -04:00
|
|
|
const char *hlua_traceback(lua_State *L, const char* sep);
|
2015-01-23 08:27:52 -05:00
|
|
|
void hlua_ctx_destroy(struct hlua *lua);
|
2015-01-23 08:06:13 -05:00
|
|
|
void hlua_init();
|
2015-01-23 06:08:30 -05:00
|
|
|
int hlua_post_init();
|
2019-08-21 08:14:50 -04:00
|
|
|
void hlua_applet_tcp_fct(struct appctx *ctx);
|
|
|
|
|
void hlua_applet_http_fct(struct appctx *ctx);
|
MEDIUM: hlua/event_hdl: initial support for event handlers
Now that the event handler API is pretty mature, we can expose it in
the lua API.
Introducing the core.event_sub(<event_types>, <cb>) lua function that
takes an array of event types <event_types> as well as a callback
function <cb> as argument.
The function returns a subscription <sub> on success.
Subscription <sub> allows you to manage the subscription from anywhere
in the script.
To this day only the sub->unsub method is implemented.
The following event types are currently supported:
- "SERVER_ADD": when a server is added
- "SERVER_DEL": when a server is removed from haproxy
- "SERVER_DOWN": server states goes from up to down
- "SERVER_UP": server states goes from down to up
As for the <cb> function: it will be called when one of the registered
event types occur. The function will be called with 3 arguments:
cb(<event>,<data>,<sub>)
<event>: event type (string) that triggered the function.
(could be any of the types used in <event_types> when registering
the subscription)
<data>: data associated with the event (specific to each event family).
For "SERVER_" family events, server details such as server name/id/proxy
will be provided.
If the server still exists (not yet deleted), a reference to the live
server is provided to spare you from an additionnal lookup if you need
to have direct access to the server from lua.
<sub> refers to the subscription. In case you need to manage it from
within an event handler.
(It refers to the same subscription that the one returned from
core.event_sub())
Subscriptions are per-thread: the thread that will be handling the
event is the one who performed the subscription using
core.event_sub() function.
Each thread treats events sequentially, it means that if you have,
let's say SERVER_UP, then SERVER_DOWN in a short timelapse, then your
cb function will first be called with SERVER_UP, and once you're done
handling the event, your function will be called again with SERVER_DOWN.
This is to ensure event consitency when it comes to logging / triggering
logic from lua.
Your lua cb function may yield if needed, but you're pleased to process
the event as fast as possible to prevent the event queue from growing up
To prevent abuses, if the event queue for the current subscription goes
over 100 unconsumed events, the subscription will pause itself
automatically for as long as it takes for your handler to catch up.
This would lead to events being missed, so a warning will be emitted in
the logs to inform you about that. This is not something you want to let
happen too often, it may indicate that you subscribed to an event that
is occurring too frequently or/and that your callback function is too
slow to keep up the pace and you should review it.
If you want to do some parallel processing because your callback
functions are slow: you might want to create subtasks from lua using
core.register_task() from within your callback function to perform the
heavy job in a dedicated task and allow remaining events to be processed
more quickly.
Please check the lua documentation for more information.
2023-02-20 12:18:59 -05:00
|
|
|
int hlua_event_sub(lua_State *L, event_hdl_sub_list *sub_list);
|
2021-03-02 10:09:26 -05:00
|
|
|
struct task *hlua_process_task(struct task *task, void *context, unsigned int state);
|
2022-06-19 11:39:33 -04:00
|
|
|
const char *hlua_show_current_location(const char *pfx);
|
2023-05-03 11:43:02 -04:00
|
|
|
int hlua_ref(lua_State *L);
|
|
|
|
|
void hlua_pushref(lua_State *L, int ref);
|
|
|
|
|
void hlua_unref(lua_State *L, int ref);
|
2023-05-04 07:59:48 -04:00
|
|
|
struct hlua *hlua_gethlua(lua_State *L);
|
2023-07-13 04:18:04 -04:00
|
|
|
void hlua_yieldk(lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k, int timeout, unsigned int flags);
|
2015-01-23 08:06:13 -05:00
|
|
|
|
2015-03-04 10:48:34 -05:00
|
|
|
#else /* USE_LUA */
|
|
|
|
|
|
2020-06-04 03:20:54 -04:00
|
|
|
/************************ For use when Lua is disabled ********************/
|
|
|
|
|
|
2015-03-03 09:17:35 -05:00
|
|
|
#define HLUA_IS_RUNNING(__hlua) 0
|
|
|
|
|
|
2015-03-04 10:48:34 -05:00
|
|
|
#define HLUA_INIT(__hlua)
|
|
|
|
|
|
|
|
|
|
/* Empty function for compilation without Lua. */
|
|
|
|
|
static inline void hlua_init() { }
|
|
|
|
|
static inline int hlua_post_init() { return 1; }
|
2015-06-17 14:18:54 -04:00
|
|
|
static inline void hlua_ctx_destroy(struct hlua *lua) { }
|
2022-06-19 11:39:33 -04:00
|
|
|
static inline const char *hlua_show_current_location(const char *pfx) { return NULL; }
|
2015-03-04 10:48:34 -05:00
|
|
|
|
|
|
|
|
#endif /* USE_LUA */
|
|
|
|
|
|
2020-06-04 03:20:54 -04:00
|
|
|
#endif /* _HAPROXY_HLUA_H */
|