mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-24 01:24:26 +01:00
plugins: make chained hooks have two different callbacks.
One is called on every plugin return, and tells us whether to continue; the other is only called if every plugin says ok. This works for things like payload replacement, where we need to process the results from each plugin, not just the final one! We should probably turn everything into a chained callback next release. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -31,15 +31,20 @@
|
||||
* - `serialize_payload` which takes a payload of type `cb_arg_type`
|
||||
* and serializes it into the given `json_stream`. `
|
||||
*
|
||||
* - `response_cb` is called once the plugin has responded (or with
|
||||
* For single-plugin hooks:
|
||||
* - `single_response_cb` is called once the plugin has responded (or with
|
||||
* buffer == NULL if there's no plugin). In addition an arbitrary
|
||||
* additional argument of type `cb_arg_type` can be passed along
|
||||
* that may contain any additional context necessary. It must free
|
||||
* or otherwise take ownership of the cb_arg_type argument.
|
||||
*
|
||||
* For chained-plugin hooks:
|
||||
* - `deserialize_cb` is called for each plugin, if it returns true the
|
||||
* next one is called, otherwise the cb_arg_type argument is free.
|
||||
* - If all `deserialize_cb` return true, `final_cb` is called. It must free
|
||||
* or otherwise take ownership of the cb_arg_type argument.
|
||||
*
|
||||
* To make hook invocations easier, each hook registered with
|
||||
* `REGISTER_PLUGIN_HOOK` provides a `plugin_hook_call_hookname`
|
||||
* To make hook invocations easier, each hook provides a `plugin_hook_call_hookname`
|
||||
* function that performs typechecking at compile time, and makes sure
|
||||
* that all the provided functions for serialization, deserialization
|
||||
* and callback have the correct type.
|
||||
@@ -57,7 +62,17 @@ struct plugin_hook {
|
||||
* register this hook, and how the hooks are called. */
|
||||
enum plugin_hook_type type;
|
||||
|
||||
void (*response_cb)(void *arg, const char *buffer, const jsmntok_t *toks);
|
||||
/* For PLUGIN_HOOK_SINGLE hooks */
|
||||
void (*single_response_cb)(void *arg,
|
||||
const char *buffer, const jsmntok_t *toks);
|
||||
|
||||
/* For PLUGIN_HOOK_CHAIN hooks: */
|
||||
/* Returns false if we should stop iterating (and free arg). */
|
||||
bool (*deserialize_cb)(void *arg,
|
||||
const char *buffer, const jsmntok_t *toks);
|
||||
void (*final_cb)(void *arg);
|
||||
|
||||
/* To send the payload to the plugin */
|
||||
void (*serialize_payload)(void *src, struct json_stream *dest);
|
||||
|
||||
/* Which plugins have registered this hook? This is a `tal_arr`
|
||||
@@ -72,6 +87,8 @@ AUTODATA_TYPE(hooks, struct plugin_hook);
|
||||
void plugin_hook_call_(struct lightningd *ld, const struct plugin_hook *hook,
|
||||
tal_t *cb_arg STEALS);
|
||||
|
||||
/* Generic deserialize_cb: returns true iff 'result': 'continue' */
|
||||
bool plugin_hook_continue(void *arg, const char *buffer, const jsmntok_t *toks);
|
||||
|
||||
/* Create a small facade in from of `plugin_hook_call_` to make sure
|
||||
* arguments are of the correct type before downcasting them to `void
|
||||
@@ -94,15 +111,39 @@ void plugin_hook_call_(struct lightningd *ld, const struct plugin_hook *hook,
|
||||
* response_cb function accepts the deserialized response format and
|
||||
* an arbitrary extra argument used to maintain context.
|
||||
*/
|
||||
#define REGISTER_PLUGIN_HOOK(name, type, response_cb, \
|
||||
serialize_payload, cb_arg_type) \
|
||||
#define REGISTER_SINGLE_PLUGIN_HOOK(name, response_cb, \
|
||||
serialize_payload, cb_arg_type) \
|
||||
struct plugin_hook name##_hook_gen = { \
|
||||
stringify(name), \
|
||||
type, \
|
||||
PLUGIN_HOOK_SINGLE, \
|
||||
typesafe_cb_cast( \
|
||||
void (*)(void *STEALS, const char *, const jsmntok_t *), \
|
||||
void (*)(cb_arg_type STEALS, const char *, const jsmntok_t *), \
|
||||
response_cb), \
|
||||
NULL, NULL, \
|
||||
typesafe_cb_cast(void (*)(void *, struct json_stream *), \
|
||||
void (*)(cb_arg_type, struct json_stream *), \
|
||||
serialize_payload), \
|
||||
NULL, /* .plugins */ \
|
||||
}; \
|
||||
AUTODATA(hooks, &name##_hook_gen); \
|
||||
PLUGIN_HOOK_CALL_DEF(name, cb_arg_type)
|
||||
|
||||
|
||||
#define REGISTER_PLUGIN_HOOK(name, deserialize_cb, final_cb, \
|
||||
serialize_payload, cb_arg_type) \
|
||||
struct plugin_hook name##_hook_gen = { \
|
||||
stringify(name), \
|
||||
PLUGIN_HOOK_CHAIN, \
|
||||
NULL, \
|
||||
typesafe_cb_cast( \
|
||||
bool (*)(void *, const char *, const jsmntok_t *), \
|
||||
bool (*)(cb_arg_type, const char *, const jsmntok_t *), \
|
||||
deserialize_cb), \
|
||||
typesafe_cb_cast( \
|
||||
void (*)(void *STEALS), \
|
||||
void (*)(cb_arg_type STEALS), \
|
||||
final_cb), \
|
||||
typesafe_cb_cast(void (*)(void *, struct json_stream *), \
|
||||
void (*)(cb_arg_type, struct json_stream *), \
|
||||
serialize_payload), \
|
||||
|
||||
Reference in New Issue
Block a user