libplugin: support wildcard subscriptions.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-07-11 07:51:36 +09:30
parent 279b3aa7e8
commit 4d507065f3
4 changed files with 32 additions and 4 deletions

View file

@ -1607,7 +1607,8 @@ static void ld_command_handle(struct plugin *plugin,
#endif
for (size_t i = 0; i < plugin->num_notif_subs; i++) {
if (streq(cmd->methodname,
plugin->notif_subs[i].name)) {
plugin->notif_subs[i].name)
|| streq(plugin->notif_subs[i].name, "*")) {
plugin->notif_subs[i].handle(cmd,
plugin->buffer,
paramstok);

View file

@ -87,6 +87,7 @@ struct plugin_option {
/* Create an array of these, one for each notification you subscribe to. */
struct plugin_notification {
/* "*" means wildcard: notify me on everything (should be last!) */
const char *name;
/* The handler must eventually trigger a `notification_handled`
* call. */

View file

@ -101,6 +101,17 @@ static struct command_result *json_shutdown(struct command *cmd,
plugin_exit(cmd->plugin, 0);
}
static struct command_result *json_all_notifs(struct command *cmd,
const char *buf,
const jsmntok_t *params)
{
plugin_log(cmd->plugin, LOG_DBG, "all: %s: %.*s",
cmd->methodname,
json_tok_full_len(params),
json_tok_full(buf, params));
return notification_handled(cmd);
}
static struct command_result *testrpc_cb(struct command *cmd,
const char *buf,
const jsmntok_t *params,
@ -209,6 +220,9 @@ static const struct plugin_notification notifs[] = { {
}, {
"shutdown",
json_shutdown
}, {
"*",
json_all_notifs
}
};

View file

@ -4252,11 +4252,14 @@ def test_plugin_persist_option(node_factory):
def test_all_subscription(node_factory, directory):
"""Ensure that registering for all notifications works."""
plugin = os.path.join(os.getcwd(), 'tests/plugins/all_notifications.py')
l1, l2 = node_factory.line_graph(2, opts={"plugin": plugin})
plugin1 = os.path.join(os.getcwd(), 'tests/plugins/all_notifications.py')
plugin2 = os.path.join(os.getcwd(), "tests/plugins/test_libplugin")
l1, l2 = node_factory.line_graph(2, opts=[{"plugin": plugin1},
{"plugin": plugin2}])
l1.stop()
l2.stop()
# There will be a lot of these!
for notstr in ("block_added: {'block_added': {'hash': ",
@ -4265,3 +4268,12 @@ def test_all_subscription(node_factory, directory):
"channel_state_changed: {'channel_state_changed': {'peer_id': ",
"shutdown: {}"):
assert l1.daemon.is_in_log(f".*plugin-all_notifications.py: notification {notstr}.*")
for notstr in ('block_added: ',
'balance_snapshot: ',
'channel_state_changed: {'):
assert l2.daemon.is_in_log(f'.*test_libplugin: all: {notstr}.*')
# shutdown and connect are subscribed before the wildcard, so is handled by that handler
assert not l2.daemon.is_in_log(f'.*test_libplugin: all: shutdown.*')
assert not l2.daemon.is_in_log(f'.*test_libplugin: all: connect.*')