avoid dbengine event loop starvation by running uv_run periodically (#19661)
Costa Tsaousis committed
Feb 17, 2025 at 18:18 UTC
12930b2792b0101bc4b94885366dfcfcbeab8cc1
2 files changed
+14
-5
src/database/engine/rrdengine.c
+13
-4
@@ -524,18 +524,19 @@ static inline bool rrdeng_cmd_has_waiting_opcodes_in_lower_priorities(STORAGE_PR
524
static inline struct rrdeng_cmd rrdeng_deq_cmd(bool from_worker) {
525
struct rrdeng_cmd *cmd = NULL;
526
enum LIBUV_WORKERS_STATUS status = work_request_full();
527
-
527
STORAGE_PRIORITY min_priority, max_priority;
529
- min_priority = STORAGE_PRIORITY_INTERNAL_DBENGINE;
530
- max_priority = (status != LIBUV_WORKERS_RELAXED) ? STORAGE_PRIORITY_INTERNAL_DBENGINE : STORAGE_PRIORITY_INTERNAL_MAX_DONT_USE - 1;
528
532
- if(from_worker) {
529
+ if(unlikely(from_worker)) {
530
if(status == LIBUV_WORKERS_CRITICAL)
531
return opcode_empty;
532
533
min_priority = STORAGE_PRIORITY_INTERNAL_QUERY_PREP;
534
max_priority = STORAGE_PRIORITY_BEST_EFFORT;
535
}
536
+ else {
537
+ min_priority = STORAGE_PRIORITY_INTERNAL_DBENGINE;
538
+ max_priority = (status != LIBUV_WORKERS_RELAXED) ? STORAGE_PRIORITY_INTERNAL_DBENGINE : STORAGE_PRIORITY_INTERNAL_MAX_DONT_USE - 1;
539
+ }
540
541
// find an opcode to execute from the queue
542
spinlock_lock(&rrdeng_main.cmd_queue.unsafe.spinlock);
@@ -1916,7 +1917,15 @@ void dbengine_event_loop(void* arg) {
1917
uv_run(&main->loop, UV_RUN_DEFAULT);
1918
1919
/* wait for commands */
1920
+ size_t count = 0;
1921
do {
1922
+ count++;
1923
+
1924
+ if(count % 100 == 0) {
1925
+ worker_is_idle();
1926
+ uv_run(&main->loop, UV_RUN_NOWAIT);
1927
+ }
1928
+
1929
worker_is_busy(RRDENG_OPCODE_MAX);
1930
cmd = rrdeng_deq_cmd(RRDENG_OPCODE_NOOP);
1931
opcode = cmd.opcode;
src/database/storage-engine.h
+1
-1
@@ -17,12 +17,12 @@ typedef enum __attribute__ ((__packed__)) storage_priority {
17
// query priorities
18
STORAGE_PRIORITY_HIGH,
19
STORAGE_PRIORITY_NORMAL,
20
+ STORAGE_PRIORITY_SYNCHRONOUS_FIRST,
21
STORAGE_PRIORITY_LOW,
22
STORAGE_PRIORITY_BEST_EFFORT,
23
24
// synchronous query, not to be dispatched to workers or queued
25
STORAGE_PRIORITY_SYNCHRONOUS,
25
- STORAGE_PRIORITY_SYNCHRONOUS_FIRST,
26
27
STORAGE_PRIORITY_INTERNAL_MAX_DONT_USE,
28
} STORAGE_PRIORITY;