mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
jsonrpc: Generalize plugin_request to jsonrpc_request
There is very little that is plugin specific in the jsonrpc_request so this just extracts the common parts so we can reuse them outside of the plugin compilation unit as well.
This commit is contained in:
parent
1a952667ee
commit
ff897f8788
@ -1027,6 +1027,42 @@ void jsonrpc_notification_end(struct jsonrpc_notification *n)
|
||||
json_stream_append(n->stream, "\n\n");
|
||||
}
|
||||
|
||||
struct jsonrpc_request *jsonrpc_request_start_(
|
||||
const tal_t *ctx, const char *method,
|
||||
void (*response_cb)(const char *buffer, const jsmntok_t *toks,
|
||||
const jsmntok_t *idtok, void *),
|
||||
void *response_cb_arg)
|
||||
{
|
||||
struct jsonrpc_request *r = tal(ctx, struct jsonrpc_request);
|
||||
static u64 next_request_id = 0;
|
||||
r->id = next_request_id++;
|
||||
r->response_cb = response_cb;
|
||||
r->response_cb_arg = response_cb_arg;
|
||||
r->method = NULL;
|
||||
r->stream = new_json_stream(r, NULL);
|
||||
|
||||
/* If no method is specified we don't prefill the JSON-RPC
|
||||
* request with the header. This serves as an escape hatch to
|
||||
* get a raw request, but get a valid request-id assigned. */
|
||||
if (method != NULL) {
|
||||
r->method = tal_strdup(r, method);
|
||||
json_object_start(r->stream, NULL);
|
||||
json_add_string(r->stream, "jsonrpc", "2.0");
|
||||
json_add_u64(r->stream, "id", r->id);
|
||||
json_add_string(r->stream, "method", method);
|
||||
json_object_start(r->stream, "params");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void jsonrpc_request_end(struct jsonrpc_request *r)
|
||||
{
|
||||
json_object_end(r->stream); /* closes '.params' */
|
||||
json_object_end(r->stream); /* closes '.' */
|
||||
json_stream_append(r->stream, "\n\n");
|
||||
}
|
||||
|
||||
/* We add this destructor as a canary to detect cmd failing. */
|
||||
static void destroy_command_canary(struct command *cmd, bool *failed)
|
||||
{
|
||||
|
@ -66,6 +66,15 @@ struct jsonrpc_notification {
|
||||
struct json_stream *stream;
|
||||
};
|
||||
|
||||
struct jsonrpc_request {
|
||||
u64 id;
|
||||
const char *method;
|
||||
struct json_stream *stream;
|
||||
void (*response_cb)(const char *buffer, const jsmntok_t *toks,
|
||||
const jsmntok_t *idtok, void *);
|
||||
void *response_cb_arg;
|
||||
};
|
||||
|
||||
/**
|
||||
* json_stream_success - start streaming a successful json result.
|
||||
* @cmd: the command we're running.
|
||||
@ -183,5 +192,22 @@ struct jsonrpc_notification *jsonrpc_notification_start(const tal_t *ctx, const
|
||||
*/
|
||||
void jsonrpc_notification_end(struct jsonrpc_notification *n);
|
||||
|
||||
#define jsonrpc_request_start(ctx, method, response_cb, response_cb_arg) \
|
||||
jsonrpc_request_start_( \
|
||||
(ctx), (method), \
|
||||
typesafe_cb_preargs(void, void *, (response_cb), (response_cb_arg), \
|
||||
const char *buffer, \
|
||||
const jsmntok_t *toks, \
|
||||
const jsmntok_t *idtok), \
|
||||
(response_cb_arg))
|
||||
|
||||
struct jsonrpc_request *jsonrpc_request_start_(
|
||||
const tal_t *ctx, const char *method,
|
||||
void (*response_cb)(const char *buffer, const jsmntok_t *toks,
|
||||
const jsmntok_t *idtok, void *),
|
||||
void *response_cb_arg);
|
||||
|
||||
void jsonrpc_request_end(struct jsonrpc_request *request);
|
||||
|
||||
AUTODATA_TYPE(json_command, struct json_command);
|
||||
#endif /* LIGHTNING_LIGHTNINGD_JSONRPC_H */
|
||||
|
@ -66,24 +66,12 @@ struct plugin {
|
||||
char **subscriptions;
|
||||
};
|
||||
|
||||
struct plugin_request {
|
||||
u64 id;
|
||||
struct json_stream *stream;
|
||||
|
||||
/* The response handler to be called when plugin gives us an object. */
|
||||
void (*cb)(const char *buffer,
|
||||
const jsmntok_t *toks,
|
||||
const jsmntok_t *idtok,
|
||||
void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
struct plugins {
|
||||
struct list_head plugins;
|
||||
size_t pending_manifests;
|
||||
|
||||
/* Currently pending requests by their request ID */
|
||||
UINTMAP(struct plugin_request *) pending_requests;
|
||||
UINTMAP(struct jsonrpc_request *) pending_requests;
|
||||
struct log *log;
|
||||
struct log_book *log_book;
|
||||
|
||||
@ -192,39 +180,29 @@ static void PRINTF_FMT(2,3) plugin_kill(struct plugin *plugin, char *fmt, ...)
|
||||
*
|
||||
* The caller needs to add the request to req->stream.
|
||||
*/
|
||||
static struct plugin_request *
|
||||
static struct jsonrpc_request *
|
||||
plugin_request_new_(struct plugin *plugin,
|
||||
const char *method,
|
||||
void (*cb)(const char *buffer,
|
||||
const jsmntok_t *toks,
|
||||
const jsmntok_t *idtok,
|
||||
void *),
|
||||
void *arg)
|
||||
{
|
||||
static u64 next_request_id = 0;
|
||||
struct plugin_request *req = tal(plugin, struct plugin_request);
|
||||
|
||||
req->id = next_request_id++;
|
||||
req->cb = cb;
|
||||
req->arg = arg;
|
||||
|
||||
/* We will not concurrently drain, if we do we must set the
|
||||
* writer to non-NULL */
|
||||
req->stream = new_json_stream(req, NULL);
|
||||
struct jsonrpc_request *req = jsonrpc_request_start(plugin, method, cb, arg);
|
||||
|
||||
/* Add to map so we can find it later when routing the response */
|
||||
uintmap_add(&plugin->plugins->pending_requests, req->id, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
#define plugin_request_new(plugin, cb, arg) \
|
||||
plugin_request_new_( \
|
||||
(plugin), \
|
||||
typesafe_cb_preargs(void, void *, (cb), (arg), \
|
||||
const char *buffer, \
|
||||
const jsmntok_t *toks, \
|
||||
const jsmntok_t *idtok), \
|
||||
(arg))
|
||||
|
||||
#define plugin_request_new(plugin, method, response_cb, response_cb_arg) \
|
||||
plugin_request_new_((plugin), (method), \
|
||||
typesafe_cb_preargs(void, void *, (response_cb), \
|
||||
(response_cb_arg), \
|
||||
const char *buffer, \
|
||||
const jsmntok_t *toks, \
|
||||
const jsmntok_t *idtok), \
|
||||
(response_cb_arg))
|
||||
/**
|
||||
* Send a JSON-RPC message (request or notification) to the plugin.
|
||||
*/
|
||||
@ -303,7 +281,7 @@ static void plugin_response_handle(struct plugin *plugin,
|
||||
const jsmntok_t *toks,
|
||||
const jsmntok_t *idtok)
|
||||
{
|
||||
struct plugin_request *request;
|
||||
struct jsonrpc_request *request;
|
||||
u64 id;
|
||||
/* We only send u64 ids, so if this fails it's a critical error (note
|
||||
* that this also works if id is inside a JSON string!). */
|
||||
@ -323,7 +301,7 @@ static void plugin_response_handle(struct plugin *plugin,
|
||||
}
|
||||
|
||||
/* We expect the request->cb to copy if needed */
|
||||
request->cb(plugin->buffer, toks, idtok, request->arg);
|
||||
request->response_cb(plugin->buffer, toks, idtok, request->response_cb_arg);
|
||||
|
||||
uintmap_del(&plugin->plugins->pending_requests, id);
|
||||
tal_free(request);
|
||||
@ -666,7 +644,7 @@ static struct command_result *plugin_rpcmethod_dispatch(struct command *cmd,
|
||||
{
|
||||
const jsmntok_t *idtok;
|
||||
struct plugin *plugin;
|
||||
struct plugin_request *req;
|
||||
struct jsonrpc_request *req;
|
||||
char id[STR_MAX_CHARS(u64)];
|
||||
|
||||
if (cmd->mode == CMD_USAGE || cmd->mode == CMD_CHECK) {
|
||||
@ -681,7 +659,7 @@ static struct command_result *plugin_rpcmethod_dispatch(struct command *cmd,
|
||||
idtok = json_get_member(buffer, toks, "id");
|
||||
assert(idtok != NULL);
|
||||
|
||||
req = plugin_request_new(plugin, plugin_rpcmethod_cb, cmd);
|
||||
req = plugin_request_new(plugin, NULL, plugin_rpcmethod_cb, cmd);
|
||||
snprintf(id, ARRAY_SIZE(id), "%"PRIu64, req->id);
|
||||
|
||||
json_stream_forward_change_id(req->stream, buffer, toks, idtok, id);
|
||||
@ -920,30 +898,13 @@ void clear_plugins(struct plugins *plugins)
|
||||
tal_free(p);
|
||||
}
|
||||
|
||||
/* For our own "getmanifest" and "init" requests: starts params[] */
|
||||
static void start_simple_request(struct plugin_request *req, const char *reqname)
|
||||
{
|
||||
json_object_start(req->stream, NULL);
|
||||
json_add_string(req->stream, "jsonrpc", "2.0");
|
||||
json_add_string(req->stream, "method", reqname);
|
||||
json_add_u64(req->stream, "id", req->id);
|
||||
}
|
||||
|
||||
static void end_simple_request(struct plugin *plugin, struct plugin_request *req)
|
||||
{
|
||||
json_object_end(req->stream);
|
||||
json_stream_append(req->stream, "\n\n");
|
||||
plugin_send(plugin, req->stream);
|
||||
req->stream = NULL;
|
||||
}
|
||||
|
||||
void plugins_init(struct plugins *plugins, const char *dev_plugin_debug)
|
||||
{
|
||||
struct plugin *p;
|
||||
char **cmd;
|
||||
int stdin, stdout;
|
||||
struct timer *expired;
|
||||
struct plugin_request *req;
|
||||
struct jsonrpc_request *req;
|
||||
plugins->pending_manifests = 0;
|
||||
uintmap_init(&plugins->pending_requests);
|
||||
|
||||
@ -969,11 +930,10 @@ void plugins_init(struct plugins *plugins, const char *dev_plugin_debug)
|
||||
* write-only on p->stdout */
|
||||
io_new_conn(p, stdout, plugin_stdout_conn_init, p);
|
||||
io_new_conn(p, stdin, plugin_stdin_conn_init, p);
|
||||
req = plugin_request_new(p, plugin_manifest_cb, p);
|
||||
start_simple_request(req, "getmanifest");
|
||||
json_array_start(req->stream, "params");
|
||||
json_array_end(req->stream);
|
||||
end_simple_request(p, req);
|
||||
req = plugin_request_new(p, "getmanifest", plugin_manifest_cb, p);
|
||||
jsonrpc_request_end(req);
|
||||
plugin_send(p, req->stream);
|
||||
|
||||
plugins->pending_manifests++;
|
||||
/* Don't timeout if they're running a debugger. */
|
||||
if (debug)
|
||||
@ -1011,13 +971,11 @@ static void plugin_config(struct plugin *plugin)
|
||||
{
|
||||
struct plugin_opt *opt;
|
||||
const char *name;
|
||||
struct plugin_request *req;
|
||||
struct jsonrpc_request *req;
|
||||
struct lightningd *ld = plugin->plugins->ld;
|
||||
|
||||
/* No writer since we don't flush concurrently. */
|
||||
req = plugin_request_new(plugin, plugin_config_cb, plugin);
|
||||
start_simple_request(req, "init");
|
||||
json_object_start(req->stream, "params"); /* start of .params */
|
||||
req = plugin_request_new(plugin, "init", plugin_config_cb, plugin);
|
||||
|
||||
/* Add .params.options */
|
||||
json_object_start(req->stream, "options");
|
||||
@ -1034,8 +992,8 @@ static void plugin_config(struct plugin *plugin)
|
||||
json_add_string(req->stream, "rpc-file", ld->rpc_filename);
|
||||
json_object_end(req->stream);
|
||||
|
||||
json_object_end(req->stream); /* end of .params */
|
||||
end_simple_request(plugin, req);
|
||||
jsonrpc_request_end(req);
|
||||
plugin_send(plugin, req->stream);
|
||||
}
|
||||
|
||||
void plugins_config(struct plugins *plugins)
|
||||
|
Loading…
Reference in New Issue
Block a user