Skip to content

Commit db1f508

Browse files
committed
sql: limit how many chainmoves/channelmoves entries we ask for at once.
This avoids latency spikes when we ask lightningd to give us 2M entries. tests/test_coinmoves.py::test_generate_coinmoves (2,000,000, sqlite3): Time (from start to end of l2 node): 88 seconds (was 95) Worst latency: 0.028 seconds **WAS 4.5** Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent bee028f commit db1f508

1 file changed

Lines changed: 27 additions & 13 deletions

File tree

plugins/sql.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -558,13 +558,18 @@ static struct command_result *wait_done(struct command *cmd,
558558
}
559559

560560
static struct command_result *one_refresh_done(struct command *cmd,
561-
struct db_query *dbq)
561+
struct db_query *dbq,
562+
bool was_limited)
562563
{
563564
struct table_desc *td = dbq->tables[0];
564565
struct list_head waiters;
565566
struct refresh_waiter *rw;
566567
struct timerel refresh_duration = timemono_since(td->refresh_start);
567568

569+
/* If we may have more, keep going. */
570+
if (was_limited)
571+
return td->refresh(cmd, dbq->tables[0], dbq);
572+
568573
/* We are no longer refreshing */
569574
assert(td->refreshing);
570575
td->refreshing = false;
@@ -873,17 +878,20 @@ static struct command_result *process_json_result(struct command *cmd,
873878
const char *buf,
874879
const jsmntok_t *result,
875880
const struct table_desc *td,
876-
u64 *last_created_index)
881+
u64 *last_created_index,
882+
size_t *num_entries)
877883
{
884+
const jsmntok_t *arr;
878885
struct timerel so_far = timemono_since(td->refresh_start);
879886
plugin_log(cmd->plugin, LOG_DBG,
880887
"Time to call %s: %"PRIu64".%09"PRIu64" seconds",
881888
td->cmdname,
882889
(u64)so_far.ts.tv_sec, (u64)so_far.ts.tv_nsec);
883890

884-
return process_json_list(cmd, buf,
885-
json_get_member(buf, result, td->arrname),
886-
NULL, td, last_created_index);
891+
arr = json_get_member(buf, result, td->arrname);
892+
if (num_entries)
893+
*num_entries = arr->size;
894+
return process_json_list(cmd, buf, arr, NULL, td, last_created_index);
887895
}
888896

889897
static struct command_result *default_list_done(struct command *cmd,
@@ -906,11 +914,11 @@ static struct command_result *default_list_done(struct command *cmd,
906914
td->name, errmsg);
907915
}
908916

909-
ret = process_json_result(cmd, buf, result, td, dbq->last_created_index);
917+
ret = process_json_result(cmd, buf, result, td, dbq->last_created_index, NULL);
910918
if (ret)
911919
return ret;
912920

913-
return one_refresh_done(cmd, dbq);
921+
return one_refresh_done(cmd, dbq, false);
914922
}
915923

916924
static struct command_result *default_refresh(struct command *cmd,
@@ -989,7 +997,7 @@ static struct command_result *listchannels_one_done(struct command *cmd,
989997
const struct table_desc *td = dbq->tables[0];
990998
struct command_result *ret;
991999

992-
ret = process_json_result(cmd, buf, result, td, dbq->last_created_index);
1000+
ret = process_json_result(cmd, buf, result, td, dbq->last_created_index, NULL);
9931001
if (ret)
9941002
return ret;
9951003

@@ -1074,7 +1082,7 @@ static struct command_result *channels_refresh(struct command *cmd,
10741082
}
10751083
}
10761084

1077-
return one_refresh_done(cmd, dbq);
1085+
return one_refresh_done(cmd, dbq, false);
10781086
}
10791087

10801088
static struct command_result *nodes_refresh(struct command *cmd,
@@ -1090,7 +1098,7 @@ static struct command_result *listnodes_one_done(struct command *cmd,
10901098
const struct table_desc *td = dbq->tables[0];
10911099
struct command_result *ret;
10921100

1093-
ret = process_json_result(cmd, buf, result, td, dbq->last_created_index);
1101+
ret = process_json_result(cmd, buf, result, td, dbq->last_created_index, NULL);
10941102
if (ret)
10951103
return ret;
10961104

@@ -1206,7 +1214,7 @@ static struct command_result *nodes_refresh(struct command *cmd,
12061214
/* FIXME: Add WIRE_GOSSIP_STORE_DELETE_NODE marker! */
12071215
}
12081216

1209-
return one_refresh_done(cmd, dbq);
1217+
return one_refresh_done(cmd, dbq, false);
12101218
}
12111219

12121220
static struct command_result *refresh_tables(struct command *cmd,
@@ -1547,6 +1555,8 @@ static const char *db_table_name(const tal_t *ctx, const char *cmdname)
15471555
return ret;
15481556
}
15491557

1558+
#define LIMIT_PER_LIST 10000
1559+
15501560
static struct command_result *limited_list_done(struct command *cmd,
15511561
const char *method,
15521562
const char *buf,
@@ -1555,12 +1565,15 @@ static struct command_result *limited_list_done(struct command *cmd,
15551565
{
15561566
struct table_desc *td = dbq->tables[0];
15571567
struct command_result *ret;
1568+
size_t num_entries;
15581569

1559-
ret = process_json_result(cmd, buf, result, td, dbq->last_created_index);
1570+
ret = process_json_result(cmd, buf, result, td, dbq->last_created_index,
1571+
&num_entries);
15601572
if (ret)
15611573
return ret;
15621574

1563-
return one_refresh_done(cmd, dbq);
1575+
/* If we got the number we asked for, we need to ask again. */
1576+
return one_refresh_done(cmd, dbq, num_entries == LIMIT_PER_LIST);
15641577
}
15651578

15661579
/* The simplest case: append-only lists */
@@ -1574,6 +1587,7 @@ static struct command_result *refresh_by_created_index(struct command *cmd,
15741587
dbq);
15751588
json_add_string(req->js, "index", "created");
15761589
json_add_u64(req->js, "start", *dbq->last_created_index + 1);
1590+
json_add_u64(req->js, "limit", LIMIT_PER_LIST);
15771591
return send_outreq(req);
15781592
}
15791593

0 commit comments

Comments
 (0)