mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
plugin_hook: special case for db hook.
I started by trying to change the current infrastructure, but this is really the only completely sync hook which makes sense; it needs to avoid doing the db_transation, as well as waiting, and using a callback is just overkill. So with some regret, I open coded it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
#include <ccan/io/io.h>
|
||||||
#include <common/memleak.h>
|
#include <common/memleak.h>
|
||||||
#include <lightningd/jsonrpc.h>
|
#include <lightningd/jsonrpc.h>
|
||||||
#include <lightningd/plugin_hook.h>
|
#include <lightningd/plugin_hook.h>
|
||||||
@@ -89,3 +90,74 @@ void plugin_hook_call_(struct lightningd *ld, const struct plugin_hook *hook,
|
|||||||
hook->response_cb(cb_arg, NULL);
|
hook->response_cb(cb_arg, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We open-code this, because it's just different and special enough to be
|
||||||
|
* annoying, and to make it clear that it's totally synchronous. */
|
||||||
|
|
||||||
|
/* Special synchronous hook for db */
|
||||||
|
static struct plugin_hook db_write_hook = { "db_write", NULL, NULL, NULL, NULL };
|
||||||
|
AUTODATA(hooks, &db_write_hook);
|
||||||
|
|
||||||
|
static void db_hook_response(const char *buffer, const jsmntok_t *toks,
|
||||||
|
const jsmntok_t *idtok,
|
||||||
|
struct plugin_hook_request *ph_req)
|
||||||
|
{
|
||||||
|
const jsmntok_t *resulttok;
|
||||||
|
bool resp;
|
||||||
|
|
||||||
|
resulttok = json_get_member(buffer, toks, "result");
|
||||||
|
if (!resulttok)
|
||||||
|
fatal("Plugin returned an invalid response to the db_write "
|
||||||
|
"hook: %s", buffer);
|
||||||
|
|
||||||
|
/* We expect result: True. Anything else we abort. */
|
||||||
|
if (!json_to_bool(buffer, resulttok, &resp))
|
||||||
|
fatal("Plugin returned an invalid result to the db_write "
|
||||||
|
"hook: %s", buffer);
|
||||||
|
|
||||||
|
/* If it fails, we must not commit to our db. */
|
||||||
|
if (!resp)
|
||||||
|
fatal("Plugin returned failed db_write: %s.", buffer);
|
||||||
|
|
||||||
|
/* We're done, exit exclusive loop. */
|
||||||
|
io_break(ph_req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_hook_db_sync(struct db *db, const char **changes, const char *final)
|
||||||
|
{
|
||||||
|
const struct plugin_hook *hook = &db_write_hook;
|
||||||
|
struct jsonrpc_request *req;
|
||||||
|
struct plugin_hook_request *ph_req;
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
if (!hook->plugin)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ph_req = notleak(tal(hook->plugin, struct plugin_hook_request));
|
||||||
|
/* FIXME: do IO logging for this! */
|
||||||
|
req = jsonrpc_request_start(NULL, hook->name, NULL, db_hook_response,
|
||||||
|
ph_req);
|
||||||
|
|
||||||
|
ph_req->hook = hook;
|
||||||
|
ph_req->db = db;
|
||||||
|
|
||||||
|
json_array_start(req->stream, "writes");
|
||||||
|
for (size_t i = 0; i < tal_count(changes); i++)
|
||||||
|
json_add_string(req->stream, NULL, changes[i]);
|
||||||
|
if (final)
|
||||||
|
json_add_string(req->stream, NULL, final);
|
||||||
|
json_array_end(req->stream);
|
||||||
|
jsonrpc_request_end(req);
|
||||||
|
|
||||||
|
plugin_request_send(hook->plugin, req);
|
||||||
|
|
||||||
|
/* We can be called on way out of an io_loop, which is already breaking.
|
||||||
|
* That will make this immediately return; save the break value and call
|
||||||
|
* again, then hand it onwards. */
|
||||||
|
ret = plugin_exclusive_loop(hook->plugin);
|
||||||
|
if (ret != ph_req) {
|
||||||
|
void *ret2 = plugin_exclusive_loop(hook->plugin);
|
||||||
|
assert(ret2 == ph_req);
|
||||||
|
io_break(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -112,4 +112,8 @@ void plugin_hook_call_(struct lightningd *ld, const struct plugin_hook *hook,
|
|||||||
|
|
||||||
bool plugin_hook_register(struct plugin *plugin, const char *method);
|
bool plugin_hook_register(struct plugin *plugin, const char *method);
|
||||||
|
|
||||||
|
/* Special sync plugin hook for db: changes[] are SQL statements, with optional
|
||||||
|
* final command appended. */
|
||||||
|
void plugin_hook_db_sync(struct db *db, const char **changes, const char *final);
|
||||||
|
|
||||||
#endif /* LIGHTNING_LIGHTNINGD_PLUGIN_HOOK_H */
|
#endif /* LIGHTNING_LIGHTNINGD_PLUGIN_HOOK_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user