@cryptotaxi247 / netdata-1 / commits / fa91f42a1

Handle incoming ACLK traffic asynchronously (#19436)

* Handle incoming aclk commands async * Process async send_alarm_snapshot (shouldn't be used) * Add batch processing * Function rename and change log to debug

Stelios Fragkakis committed Jan 20, 2025 at 01:47 UTC fa91f42a15470c6ed1d478cbe40f89de81d2d6b8
9 files changed +261 -105
src/aclk/aclk.c
+4 -4
@@ -953,7 +953,7 @@ void aclk_host_state_update(RRDHOST *host, int cmd, int queryable)
953 "Registering host=%s, hops=%d", host->machine_guid,
954 rrdhost_ingestion_hops(host));
955
956 - aclk_execute_query(create_query);
956 + aclk_add_job(create_query);
957 return;
958 }
959 }
@@ -982,7 +982,7 @@ void aclk_host_state_update(RRDHOST *host, int cmd, int queryable)
982 freez((void*)node_state_update.node_id);
983 query->data.bin_payload.msg_name = "UpdateNodeInstanceConnection";
984 query->data.bin_payload.topic = ACLK_TOPICID_NODE_CONN;
985 - aclk_execute_query(query);
985 + aclk_add_job(query);
986 }
987
988 void aclk_send_node_instances()
@@ -1028,7 +1028,7 @@ void aclk_send_node_instances()
1028 freez((void*)node_state_update.node_id);
1029 query->data.bin_payload.msg_name = "UpdateNodeInstanceConnection";
1030 query->data.bin_payload.topic = ACLK_TOPICID_NODE_CONN;
1031 - aclk_execute_query(query);
1031 + aclk_add_job(query);
1032 } else {
1033 aclk_query_t create_query;
1034 create_query = aclk_query_new(REGISTER_NODE);
@@ -1050,7 +1050,7 @@ void aclk_send_node_instances()
1050 (char*)node_instance_creation.machine_guid, list->hops);
1051
1052 freez((void *)node_instance_creation.machine_guid);
1053 - aclk_execute_query(create_query);
1053 + aclk_add_job(create_query);
1054 }
1055 freez(list->hostname);
1056
src/aclk/aclk_query_queue.h
+10 -2
@@ -23,6 +23,9 @@ typedef enum {
23 CTX_CHECKPOINT, // Context checkpoint from the cloud
24 CTX_STOP_STREAMING, // Context stop streaming
25 CREATE_NODE_INSTANCE, // Create node instance on the agent
26 + SEND_NODE_INSTANCES, // Send node instances to the cloud
27 + ALERT_START_STREAMING, // Start alert streaming from cloud
28 + ALERT_CHECKPOINT, // Do an alert version check
29 ACLK_QUERY_TYPE_COUNT // always keep this as last
30 } aclk_query_type_t;
31
@@ -50,17 +53,21 @@ struct aclk_query {
53 char *dedup_id;
54 char *callback_topic;
55 char *msg_id;
56 + union {
57 + char *claim_id;
58 + char *machine_guid;
59 + };
60
61 struct timeval created_tv;
62 usec_t created;
63 int timeout;
64
58 - // TODO maybe remove?
59 - int version;
65 + uint64_t version;
66 union {
67 struct aclk_query_http_api_v2 http_api_v2;
68 struct aclk_bin_payload bin_payload;
69 void *payload;
70 + char *node_id;
71 } data;
72 };
73
@@ -68,6 +75,7 @@ aclk_query_t aclk_query_new(aclk_query_type_t type);
75 void aclk_query_free(aclk_query_t query);
76
77 void aclk_execute_query(aclk_query_t query);
78 +void aclk_add_job(aclk_query_t query);
79
80 #define QUEUE_IF_PAYLOAD_PRESENT(query) \
81 do { \
src/aclk/aclk_rx_msgs.c
+33 -59
@@ -255,49 +255,11 @@ int create_node_instance_result(const char *msg, size_t msg_len)
255
256 netdata_log_debug(D_ACLK, "CreateNodeInstanceResult: guid:%s nodeid:%s", res.machine_guid, res.node_id);
257
258 - nd_uuid_t host_id, node_id;
259 - if (uuid_parse(res.machine_guid, host_id)) {
260 - netdata_log_error("Error parsing machine_guid provided by CreateNodeInstanceResult");
261 - freez(res.machine_guid);
262 - freez(res.node_id);
263 - return 1;
264 - }
265 - if (uuid_parse(res.node_id, node_id)) {
266 - netdata_log_error("Error parsing node_id provided by CreateNodeInstanceResult");
267 - freez(res.machine_guid);
268 - freez(res.node_id);
269 - return 1;
270 - }
271 - sql_update_node_id(&host_id, &node_id);
272 -
273 - aclk_query_t query = aclk_query_new(NODE_STATE_UPDATE);
274 - node_instance_connection_t node_state_update = {
275 - .hops = 1,
276 - .live = 0,
277 - .queryable = 1,
278 - .session_id = aclk_session_newarch,
279 - .node_id = res.node_id,
280 - .capabilities = NULL
281 - };
282 -
283 - RRDHOST *host = rrdhost_find_by_guid(res.machine_guid);
284 - if (likely(host)) {
285 - node_state_update.live = rrdhost_is_local(host) ? 1 : 0;
286 - node_state_update.hops = rrdhost_ingestion_hops(host);
287 - node_state_update.capabilities = aclk_get_node_instance_capas(host);
288 - schedule_node_state_update(host, 5000);
289 - }
290 -
291 - CLAIM_ID claim_id = claim_id_get();
292 - node_state_update.claim_id = claim_id_is_set(claim_id) ? claim_id.str : NULL;
293 - query->data.bin_payload.payload = generate_node_instance_connection(&query->data.bin_payload.size, &node_state_update);
294 -
295 - freez((void *)node_state_update.capabilities);
296 -
297 - query->data.bin_payload.msg_name = "UpdateNodeInstanceConnection";
298 - query->data.bin_payload.topic = ACLK_TOPICID_NODE_CONN;
258 + aclk_query_t query = aclk_query_new(CREATE_NODE_INSTANCE);
259 + query->data.node_id = strdupz(res.node_id);
260 + query->machine_guid = strdupz(res.machine_guid);
261 + aclk_add_job(query);
262
300 - aclk_execute_query(query);
263 freez(res.node_id);
264 freez(res.machine_guid);
265 return 0;
@@ -307,7 +269,8 @@ int send_node_instances(const char *msg, size_t msg_len)
269 {
270 UNUSED(msg);
271 UNUSED(msg_len);
310 - aclk_send_node_instances();
272 + aclk_query_t query = aclk_query_new(SEND_NODE_INSTANCES);
273 + aclk_add_job(query);
274 return 0;
275 }
276
@@ -342,7 +305,10 @@ int start_alarm_streaming(const char *msg, size_t msg_len)
305 netdata_log_error("Error parsing StartAlarmStreaming");
306 return 1;
307 }
345 - aclk_start_alert_streaming(res.node_id, res.version);
308 + aclk_query_t query = aclk_query_new(ALERT_START_STREAMING);
309 + query->data.node_id = strdupz(res.node_id);
310 + query->version = res.version;
311 + aclk_add_job(query);
312 freez(res.node_id);
313 return 0;
314 }
@@ -356,7 +322,11 @@ int send_alarm_checkpoint(const char *msg, size_t msg_len)
322 freez(sac.claim_id);
323 return 1;
324 }
359 - aclk_alert_version_check(sac.node_id, sac.claim_id, sac.version);
325 + aclk_query_t query = aclk_query_new(ALERT_CHECKPOINT);
326 + query->data.node_id = strdupz(sac.node_id);
327 + query->claim_id = strdupz(sac.claim_id);
328 + query->version = sac.version;
329 + aclk_add_job(query);
330 freez(sac.node_id);
331 freez(sac.claim_id);
332 return 0;
@@ -383,7 +353,11 @@ int send_alarm_snapshot(const char *msg, size_t msg_len)
353 destroy_send_alarm_snapshot(sas);
354 return 1;
355 }
386 - aclk_process_send_alarm_snapshot(sas->node_id, sas->claim_id, sas->snapshot_uuid);
356 + aclk_query_t query = aclk_query_new(ALERT_CHECKPOINT);
357 + query->data.node_id = strdupz(sas->node_id);
358 + query->claim_id = strdupz(sas->claim_id);
359 + query->version = 0; // force snapshot
360 + aclk_add_job(query);
361 destroy_send_alarm_snapshot(sas);
362 return 0;
363 }
@@ -420,7 +394,7 @@ int contexts_checkpoint(const char *msg, size_t msg_len)
394
395 aclk_query_t query = aclk_query_new(CTX_CHECKPOINT);
396 query->data.payload = cmd;
423 - aclk_execute_query(query);
397 + aclk_add_job(query);
398 return 0;
399 }
400
@@ -437,7 +411,7 @@ int stop_streaming_contexts(const char *msg, size_t msg_len)
411
412 aclk_query_t query = aclk_query_new(CTX_STOP_STREAMING);
413 query->data.payload = cmd;
440 - aclk_execute_query(query);
414 + aclk_add_job(query);
415 return 0;
416 }
417
@@ -466,18 +440,18 @@ typedef struct {
440
441 new_cloud_rx_msg_t rx_msgs[] = {
442 { .name = "cmd", .name_hash = 0, .fnc = handle_old_proto_cmd },
469 - { .name = "CreateNodeInstanceResult", .name_hash = 0, .fnc = create_node_instance_result },
470 - { .name = "SendNodeInstances", .name_hash = 0, .fnc = send_node_instances },
471 - { .name = "StreamChartsAndDimensions", .name_hash = 0, .fnc = stream_charts_and_dimensions },
472 - { .name = "ChartsAndDimensionsAck", .name_hash = 0, .fnc = charts_and_dimensions_ack },
473 - { .name = "UpdateChartConfigs", .name_hash = 0, .fnc = update_chart_configs },
474 - { .name = "StartAlarmStreaming", .name_hash = 0, .fnc = start_alarm_streaming },
475 - { .name = "SendAlarmCheckpoint", .name_hash = 0, .fnc = send_alarm_checkpoint },
476 - { .name = "SendAlarmConfiguration", .name_hash = 0, .fnc = send_alarm_configuration },
477 - { .name = "SendAlarmSnapshot", .name_hash = 0, .fnc = send_alarm_snapshot },
443 + { .name = "CreateNodeInstanceResult", .name_hash = 0, .fnc = create_node_instance_result }, // async
444 + { .name = "SendNodeInstances", .name_hash = 0, .fnc = send_node_instances }, // async
445 + { .name = "StreamChartsAndDimensions", .name_hash = 0, .fnc = stream_charts_and_dimensions }, // unused
446 + { .name = "ChartsAndDimensionsAck", .name_hash = 0, .fnc = charts_and_dimensions_ack }, // unused
447 + { .name = "UpdateChartConfigs", .name_hash = 0, .fnc = update_chart_configs }, // unused
448 + { .name = "StartAlarmStreaming", .name_hash = 0, .fnc = start_alarm_streaming }, // async
449 + { .name = "SendAlarmCheckpoint", .name_hash = 0, .fnc = send_alarm_checkpoint }, // async
450 + { .name = "SendAlarmConfiguration", .name_hash = 0, .fnc = send_alarm_configuration }, // async
451 + { .name = "SendAlarmSnapshot", .name_hash = 0, .fnc = send_alarm_snapshot }, // shouldn't be used
452 { .name = "DisconnectReq", .name_hash = 0, .fnc = handle_disconnect_req },
479 - { .name = "ContextsCheckpoint", .name_hash = 0, .fnc = contexts_checkpoint },
480 - { .name = "StopStreamingContexts", .name_hash = 0, .fnc = stop_streaming_contexts },
453 + { .name = "ContextsCheckpoint", .name_hash = 0, .fnc = contexts_checkpoint }, // async
454 + { .name = "StopStreamingContexts", .name_hash = 0, .fnc = stop_streaming_contexts }, // async
455 { .name = "CancelPendingRequest", .name_hash = 0, .fnc = cancel_pending_req },
456 { .name = NULL, .name_hash = 0, .fnc = NULL },
457 };
src/daemon/libuv_workers.c
+4
@@ -71,6 +71,10 @@ void register_libuv_worker_jobs() {
71 worker_register_job_name(UV_EVENT_CTX_SEND_SNAPSHOT, "ctx send snapshot");
72 worker_register_job_name(UV_EVENT_CTX_SEND_SNAPSHOT_UPD, "ctx send update");
73 worker_register_job_name(UV_EVENT_NODE_STATE_UPDATE, "node state update");
74 + worker_register_job_name(UV_EVENT_SEND_NODE_INSTANCES, "send node instances");
75 + worker_register_job_name(UV_EVENT_ALERT_START_STREAMING, "alert start streaming");
76 + worker_register_job_name(UV_EVENT_ALERT_CHECKPOINT, "alert checkpoint");
77 + worker_register_job_name(UV_EVENT_CREATE_NODE_INSTANCE, "create node instance");
78
79 // netdatacli
80 worker_register_job_name(UV_EVENT_SCHEDULE_CMD, "schedule command");
src/daemon/libuv_workers.h
+4
@@ -64,6 +64,10 @@ enum event_loop_job {
64 UV_EVENT_CTX_SEND_SNAPSHOT,
65 UV_EVENT_CTX_SEND_SNAPSHOT_UPD,
66 UV_EVENT_NODE_STATE_UPDATE,
67 + UV_EVENT_SEND_NODE_INSTANCES,
68 + UV_EVENT_ALERT_START_STREAMING,
69 + UV_EVENT_ALERT_CHECKPOINT,
70 + UV_EVENT_CREATE_NODE_INSTANCE,
71
72 // netdatacli
73 UV_EVENT_SCHEDULE_CMD,
src/database/sqlite/sqlite_aclk.c
+204 -9
@@ -11,6 +11,55 @@ void sanity_check(void) {
11 #include "sqlite_aclk_node.h"
12 #include "../aclk_query_queue.h"
13 #include "../aclk_query.h"
14 +#include "../aclk_capas.h"
15 +
16 +static void create_node_instance_result_job(const char *machine_guid, const char *node_id)
17 +{
18 + nd_uuid_t host_uuid, node_uuid;
19 +
20 + if (uuid_parse(machine_guid, host_uuid)) {
21 + netdata_log_error("Error parsing machine_guid provided by CreateNodeInstanceResult");
22 + return;
23 + }
24 +
25 + if (uuid_parse(node_id, node_uuid)) {
26 + netdata_log_error("Error parsing node_id provided by CreateNodeInstanceResult");
27 + return;
28 + }
29 +
30 + RRDHOST *host = rrdhost_find_by_guid(machine_guid);
31 + if (unlikely(!host)) {
32 + netdata_log_error("Cannot find machine_guid provided by CreateNodeInstanceResult");
33 + return;
34 + }
35 +
36 + sql_update_node_id(&host_uuid, &node_uuid);
37 +
38 + aclk_query_t query = aclk_query_new(NODE_STATE_UPDATE);
39 + node_instance_connection_t node_state_update = {
40 + .hops = 1,
41 + .live = 0,
42 + .queryable = 1,
43 + .session_id = aclk_session_newarch,
44 + .node_id = node_id,
45 + .capabilities = NULL};
46 +
47 + node_state_update.live = rrdhost_is_local(host) ? 1 : 0;
48 + node_state_update.hops = rrdhost_ingestion_hops(host);
49 + node_state_update.capabilities = aclk_get_node_instance_capas(host);
50 + schedule_node_state_update(host, 5000);
51 +
52 + CLAIM_ID claim_id = claim_id_get();
53 + node_state_update.claim_id = claim_id_is_set(claim_id) ? claim_id.str : NULL;
54 + query->data.bin_payload.payload = generate_node_instance_connection(&query->data.bin_payload.size, &node_state_update);
55 +
56 + freez((void *)node_state_update.capabilities);
57 +
58 + query->data.bin_payload.msg_name = "UpdateNodeInstanceConnection";
59 + query->data.bin_payload.topic = ACLK_TOPICID_NODE_CONN;
60 +
61 + aclk_add_job(query);
62 +}
63
64 struct aclk_sync_config_s {
65 uv_thread_t thread;
@@ -21,7 +70,9 @@ struct aclk_sync_config_s {
70 mqtt_wss_client client;
71 int aclk_queries_running;
72 bool alert_push_running;
73 + bool aclk_batch_job_is_running;
74 SPINLOCK cmd_queue_lock;
75 + uint32_t aclk_jobs_pending;
76 struct aclk_database_cmd *cmd_base;
77 } aclk_sync_config = { 0 };
78
@@ -269,6 +320,11 @@ static int aclk_config_parameters(void *data __maybe_unused, int argc __maybe_un
320 return 0;
321 }
322
323 +struct judy_list_t {
324 + Pvoid_t JudyL;
325 + Word_t count;
326 +};
327 +
328 static void async_cb(uv_async_t *handle)
329 {
330 uv_stop(handle->loop);
@@ -281,12 +337,18 @@ static void timer_cb(uv_timer_t *handle)
337 {
338 uv_stop(handle->loop);
339 uv_update_time(handle->loop);
340 + struct aclk_sync_config_s *config = handle->data;
341
342 struct aclk_database_cmd cmd = { 0 };
343 if (aclk_online_for_alerts()) {
344 cmd.opcode = ACLK_DATABASE_PUSH_ALERT;
345 aclk_database_enq_cmd(&cmd);
346 }
347 +
348 + if (config->aclk_jobs_pending > 0) {
349 + cmd.opcode = ACLK_QUERY_BATCH_EXECUTE;
350 + aclk_database_enq_cmd(&cmd);
351 + }
352 }
353
354 struct aclk_query_payload {
@@ -315,6 +377,8 @@ static void aclk_run_query(struct aclk_sync_config_s *config, aclk_query_t query
377 bool ok_to_send = true;
378
379 switch (query->type) {
380 +
381 +// Incoming : cloud -> agent
382 case HTTP_API_V2:
383 if (is_worker)
384 worker_is_busy(UV_EVENT_ACLK_QUERY_EXECUTE);
@@ -341,6 +405,37 @@ static void aclk_run_query(struct aclk_sync_config_s *config, aclk_query_t query
405 freez(cmd);
406 ok_to_send = false;
407 break;
408 + case SEND_NODE_INSTANCES:
409 + if (is_worker)
410 + worker_is_busy(UV_EVENT_SEND_NODE_INSTANCES);
411 + aclk_send_node_instances();
412 + ok_to_send = false;
413 + break;
414 + case ALERT_START_STREAMING:
415 + if (is_worker)
416 + worker_is_busy(UV_EVENT_ALERT_START_STREAMING);
417 + aclk_start_alert_streaming(query->data.node_id, query->version);
418 + freez(query->data.node_id);
419 + ok_to_send = false;
420 + break;
421 + case ALERT_CHECKPOINT:
422 + if (is_worker)
423 + worker_is_busy(UV_EVENT_ALERT_CHECKPOINT);
424 + aclk_alert_version_check(query->data.node_id, query->claim_id, query->version);
425 + freez(query->data.node_id);
426 + freez(query->claim_id);
427 + ok_to_send = false;
428 + break;
429 + case CREATE_NODE_INSTANCE:
430 + if (is_worker)
431 + worker_is_busy(UV_EVENT_CREATE_NODE_INSTANCE);
432 + create_node_instance_result_job(query->machine_guid, query->data.node_id);
433 + freez(query->data.node_id);
434 + freez(query->machine_guid);
435 + ok_to_send = false;
436 + break;
437 +
438 +// Outgoing: agent -> cloud
439 case ALARM_PROVIDE_CFG:
440 if (is_worker)
441 worker_is_busy(UV_EVENT_ALARM_PROVIDE_CFG);
@@ -378,8 +473,10 @@ static void aclk_run_query(struct aclk_sync_config_s *config, aclk_query_t query
473 ok_to_send = false;
474 break;
475 }
476 +
477 if (ok_to_send)
478 send_bin_msg(config->client, query);
479 +
480 aclk_query_free(query);
481 }
482
@@ -395,6 +492,51 @@ static void aclk_run_query_job(uv_work_t *req)
492 worker_is_idle();
493 }
494
495 +static void after_aclk_execute_batch(uv_work_t *req, int status __maybe_unused)
496 +{
497 + struct aclk_query_payload *payload = req->data;
498 + struct aclk_sync_config_s *config = payload->config;
499 + config->aclk_batch_job_is_running = false;
500 + freez(payload);
501 +}
502 +
503 +static void aclk_execute_batch(uv_work_t *req)
504 +{
505 + register_libuv_worker_jobs();
506 +
507 + struct aclk_query_payload *payload = req->data;
508 + struct aclk_sync_config_s *config = payload->config;
509 + struct judy_list_t *aclk_query_batch = payload->data;
510 +
511 + if (!aclk_query_batch)
512 + return;
513 +
514 + usec_t started_ut = now_monotonic_usec(); (void)started_ut;
515 +
516 + size_t entries = aclk_query_batch->count;
517 + Word_t Index = 0;
518 + bool first = true;
519 + Pvoid_t *PValue;
520 + while ((PValue = JudyLFirstThenNext(aclk_query_batch->JudyL, &Index, &first))) {
521 + if (!*PValue)
522 + continue;
523 +
524 + aclk_query_t query = *PValue;
525 + aclk_run_query(config, query, true);
526 + }
527 +
528 + (void) JudyLFreeArray(&aclk_query_batch->JudyL, PJE0);
529 + freez(aclk_query_batch);
530 +
531 + usec_t ended_ut = now_monotonic_usec();
532 + (void)ended_ut;
533 + nd_log_daemon(
534 + NDLP_DEBUG, "Processed %zu ACLK commands in %0.2f ms", entries, (double)(ended_ut - started_ut) / USEC_PER_MS);
535 +
536 + worker_is_idle();
537 +}
538 +
539 +
540 static void node_update_timer_cb(uv_timer_t *handle)
541 {
542 struct aclk_sync_cfg_t *ahc = handle->data;
@@ -441,6 +583,8 @@ static void start_alert_push(uv_work_t *req __maybe_unused)
583 worker_is_idle();
584 }
585
586 +#define MAX_ACLK_BATCH_JOBS_IN_QUEUE (20)
587 +
588 static void aclk_synchronization(void *arg)
589 {
590 struct aclk_sync_config_s *config = arg;
@@ -448,11 +592,13 @@ static void aclk_synchronization(void *arg)
592 worker_register("ACLKSYNC");
593 service_register(SERVICE_THREAD_TYPE_EVENT_LOOP, NULL, NULL, NULL, true);
594
451 - worker_register_job_name(ACLK_DATABASE_NOOP, "noop");
452 - worker_register_job_name(ACLK_DATABASE_NODE_STATE, "node state");
453 - worker_register_job_name(ACLK_DATABASE_PUSH_ALERT, "alert push");
454 - worker_register_job_name(ACLK_DATABASE_PUSH_ALERT_CONFIG, "alert conf push");
455 - worker_register_job_name(ACLK_QUERY_EXECUTE_SYNC, "aclk query execute sync");
595 + worker_register_job_name(ACLK_DATABASE_NOOP, "noop");
596 + worker_register_job_name(ACLK_DATABASE_NODE_STATE, "node state");
597 + worker_register_job_name(ACLK_DATABASE_PUSH_ALERT, "alert push");
598 + worker_register_job_name(ACLK_DATABASE_PUSH_ALERT_CONFIG, "alert conf push");
599 + worker_register_job_name(ACLK_QUERY_EXECUTE_SYNC, "aclk query execute sync");
600 + worker_register_job_name(ACLK_QUERY_BATCH_EXECUTE, "aclk batch execute");
601 + worker_register_job_name(ACLK_QUERY_BATCH_ADD, "aclk batch add");
602
603 uv_loop_t *loop = &config->loop;
604 fatal_assert(0 == uv_loop_init(loop));
@@ -472,6 +618,10 @@ static void aclk_synchronization(void *arg)
618 netdata_log_info("Starting ACLK synchronization thread with %d parallel query threads", query_thread_count);
619
620 struct alert_push_data *data;
621 + aclk_query_t query;
622 + struct judy_list_t *aclk_query_batch = NULL;
623 + Pvoid_t *Pvalue;
624 + struct aclk_query_payload *payload;
625
626 while (likely(service_running(SERVICE_ACLK))) {
627 enum aclk_database_opcode opcode;
@@ -555,10 +705,9 @@ static void aclk_synchronization(void *arg)
705 config->client = (mqtt_wss_client) cmd.param[0];
706 break;
707
558 - case ACLK_QUERY_EXECUTE:;
559 - aclk_query_t query = (aclk_query_t)cmd.param[0];
560 -
561 - struct aclk_query_payload *payload = NULL;
708 + case ACLK_QUERY_EXECUTE:
709 + query = (aclk_query_t)cmd.param[0];
710 + payload = NULL;
711 config->aclk_queries_running++;
712 bool execute_now = (config->aclk_queries_running > query_thread_count);
713 if (!execute_now) {
@@ -577,6 +726,44 @@ static void aclk_synchronization(void *arg)
726 }
727 break;
728
729 +// Note: The following two opcodes must be in this order
730 + case ACLK_QUERY_BATCH_ADD:
731 + query = (aclk_query_t)cmd.param[0];
732 + if (!query)
733 + break;
734 +
735 + if (!aclk_query_batch)
736 + aclk_query_batch = callocz(1, sizeof(*aclk_query_batch));
737 +
738 + Pvalue = JudyLIns(&aclk_query_batch->JudyL, ++aclk_query_batch->count, PJE0);
739 + if (Pvalue)
740 + *Pvalue = query;
741 +
742 + config->aclk_jobs_pending++;
743 + if (aclk_query_batch->count < MAX_ACLK_BATCH_JOBS_IN_QUEUE || config->aclk_batch_job_is_running)
744 + break;
745 + // fall through
746 + case ACLK_QUERY_BATCH_EXECUTE:
747 + if (!aclk_query_batch || config->aclk_batch_job_is_running)
748 + break;
749 +
750 + payload = mallocz(sizeof(*payload));
751 + payload->request.data = payload;
752 + payload->config = config;
753 + payload->data = aclk_query_batch;
754 +
755 + config->aclk_batch_job_is_running = true;
756 + config->aclk_jobs_pending -= aclk_query_batch->count;
757 + aclk_query_batch = NULL;
758 +
759 + if (uv_queue_work(loop, &payload->request, aclk_execute_batch, after_aclk_execute_batch)) {
760 + aclk_query_batch = payload->data;
761 + config->aclk_jobs_pending += aclk_query_batch->count;
762 + freez(payload);
763 + config->aclk_batch_job_is_running = false;
764 + }
765 + break;
766 +
767 default:
768 break;
769 }
@@ -702,6 +889,14 @@ void aclk_execute_query(aclk_query_t query)
889 queue_aclk_sync_cmd(ACLK_QUERY_EXECUTE, query, NULL);
890 }
891
892 +void aclk_add_job(aclk_query_t query)
893 +{
894 + if (unlikely(!aclk_sync_config.initialized))
895 + return;
896 +
897 + queue_aclk_sync_cmd(ACLK_QUERY_BATCH_ADD, query, NULL);
898 +}
899 +
900 void aclk_query_init(mqtt_wss_client client) {
901
902 queue_aclk_sync_cmd(ACLK_MQTT_WSS_CLIENT, client, NULL);
src/database/sqlite/sqlite_aclk.h
+2
@@ -24,6 +24,8 @@ enum aclk_database_opcode {
24 ACLK_MQTT_WSS_CLIENT,
25 ACLK_QUERY_EXECUTE,
26 ACLK_QUERY_EXECUTE_SYNC,
27 + ACLK_QUERY_BATCH_ADD,
28 + ACLK_QUERY_BATCH_EXECUTE,
29
30 // leave this last
31 // we need it to check for worker utilization
src/database/sqlite/sqlite_aclk_alert.c
-30
@@ -819,36 +819,6 @@ static void schedule_alert_snapshot_if_needed(struct aclk_sync_cfg_t *wc, uint64
819 wc->checkpoint_count++;
820 }
821
822 -void aclk_process_send_alarm_snapshot(char *node_id, char *claim_id __maybe_unused, char *snapshot_uuid)
823 -{
824 - nd_uuid_t node_uuid;
825 -
826 - if (unlikely(!node_id || uuid_parse(node_id, node_uuid)))
827 - return;
828 -
829 - struct aclk_sync_cfg_t *wc;
830 -
831 - RRDHOST *host = find_host_by_node_id(node_id);
832 - if (unlikely(!host || !(wc = host->aclk_config))) {
833 - nd_log(NDLS_ACCESS, NDLP_WARNING, "ACLK STA [%s (N/A)]: ACLK node id does not exist", node_id);
834 - return;
835 - }
836 -
837 - nd_log(NDLS_ACCESS, NDLP_DEBUG,
838 - "IN [%s (%s)]: Request to send alerts snapshot, snapshot_uuid %s",
839 - node_id,
840 - wc->host ? rrdhost_hostname(wc->host) : "N/A",
841 - snapshot_uuid);
842 -
843 - if (wc->alerts_snapshot_uuid && !strcmp(wc->alerts_snapshot_uuid,snapshot_uuid))
844 - return;
845 -
846 - wc->alerts_snapshot_uuid = strdupz(snapshot_uuid);
847 -
848 - wc->send_snapshot = 1;
849 - rrdhost_flag_set(host, RRDHOST_FLAG_ACLK_STREAM_ALERTS);
850 -}
851 -
822 #define SQL_COUNT_SNAPSHOT_ENTRIES \
823 "SELECT COUNT(1) FROM alert_version av, health_log hl " \
824 "WHERE hl.host_id = @host_id AND hl.health_log_id = av.health_log_id AND av.status <> -2"
src/database/sqlite/sqlite_aclk_alert.h
-1
@@ -11,7 +11,6 @@ void aclk_start_alert_streaming(char *node_id, uint64_t cloud_version);
11 void aclk_alert_version_check(char *node_id, char *claim_id, uint64_t cloud_version);
12
13 void send_alert_snapshot_to_cloud(RRDHOST *host __maybe_unused);
14 -void aclk_process_send_alarm_snapshot(char *node_id, char *claim_id, char *snapshot_uuid);
14 bool process_alert_pending_queue(RRDHOST *host);
15 void aclk_push_alert_events_for_all_hosts(void);
16 uint64_t calculate_node_alert_version(RRDHOST *host);