ACLK synchronization improvements (#20077)
ACLK synchronization configuration handling and update related functions Add OPCODEs to properly create/stop/destroy ACLK host notification related timer
Stelios Fragkakis committed
Apr 7, 2025 at 23:59 UTC
0e73b7f06c29adaad2f615aec8f2d00dc9895a24
11 files changed
+207
-133
src/aclk/aclk.c
+15
-22
@@ -1035,20 +1035,20 @@ void aclk_send_bin_msg(char *msg, size_t msg_len, enum aclk_topics subtopic, con
1035
1036
static void fill_alert_status_for_host(BUFFER *wb, RRDHOST *host)
1037
{
1038
- struct aclk_sync_cfg_t *wc = host->aclk_config;
1039
- if (!wc)
1038
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
1039
+ if (!aclk_host_config)
1040
return;
1041
1042
- buffer_sprintf(wb,
1042
+ buffer_sprintf(
1043
+ wb,
1044
"\n\t\tUpdates: %d"
1045
"\n\t\tCheckpoints: %d"
1046
"\n\t\tAlert count: %d"
1047
"\n\t\tAlert snapshot count: %d",
1047
- wc->stream_alerts,
1048
- wc->checkpoint_count,
1049
- wc->alert_count,
1050
- wc->snapshot_count
1051
- );
1048
+ aclk_host_config->stream_alerts,
1049
+ aclk_host_config->checkpoint_count,
1050
+ aclk_host_config->alert_count,
1051
+ aclk_host_config->snapshot_count);
1052
}
1053
1054
char *aclk_state(void)
@@ -1137,22 +1137,22 @@ char *aclk_state(void)
1137
1138
static void fill_alert_status_for_host_json(json_object *obj, RRDHOST *host)
1139
{
1140
- struct aclk_sync_cfg_t *wc = host->aclk_config;
1141
- if (!wc)
1140
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
1141
+ if (!aclk_host_config)
1142
return;
1143
1144
- json_object *tmp = json_object_new_int(wc->stream_alerts);
1144
+ json_object *tmp = json_object_new_int(aclk_host_config->stream_alerts);
1145
json_object_object_add(obj, "updates", tmp);
1146
1147
- tmp = json_object_new_int(wc->checkpoint_count);
1147
+ tmp = json_object_new_int(aclk_host_config->checkpoint_count);
1148
json_object_object_add(obj, "checkpoint-count", tmp);
1149
1150
- tmp = json_object_new_int(wc->alert_count);
1150
+ tmp = json_object_new_int(aclk_host_config->alert_count);
1151
json_object_object_add(obj, "alert-count", tmp);
1152
1153
- tmp = json_object_new_int(wc->snapshot_count);
1153
+ tmp = json_object_new_int(aclk_host_config->snapshot_count);
1154
json_object_object_add(obj, "alert-snapshot-count", tmp);
1155
- tmp = json_object_new_int64(calculate_node_alert_version(wc->host));
1155
+ tmp = json_object_new_int64(calculate_node_alert_version(aclk_host_config->host));
1156
json_object_object_add(obj, "alert-version", tmp);
1157
}
1158
@@ -1302,10 +1302,3 @@ void add_aclk_host_labels(void) {
1302
rrdlabels_add(labels, "_aclk_proxy", proxy_str, RRDLABEL_SRC_AUTO);
1303
rrdlabels_add(labels, "_aclk_ng_new_cloud_protocol", "true", RRDLABEL_SRC_AUTO|RRDLABEL_SRC_ACLK);
1304
}
1305
-
1306
-void aclk_queue_node_info(RRDHOST *host, bool immediate)
1307
-{
1308
- struct aclk_sync_cfg_t *wc = host->aclk_config;
1309
- if (wc)
1310
- wc->node_info_send_time = (host == localhost || immediate) ? 1 : now_realtime_sec();
1311
-}
src/aclk/aclk.h
-1
@@ -103,7 +103,6 @@ void aclk_send_bin_msg(char *msg, size_t msg_len, enum aclk_topics subtopic, con
103
char *aclk_state(void);
104
char *aclk_state_json(void);
105
void add_aclk_host_labels(void);
106
-void aclk_queue_node_info(RRDHOST *host, bool immediate);
106
107
struct mqtt_wss_stats aclk_statistics(void);
108
void aclk_status_set(ACLK_STATUS status);
src/database/rrdhost.h
+1
-1
@@ -253,7 +253,7 @@ struct rrdhost {
253
254
// ------------------------------------------------------------------------
255
256
- struct aclk_sync_cfg_t *aclk_config;
256
+ struct aclk_sync_cfg_t *aclk_host_config;
257
258
// ------------------------------------------------------------------------
259
// health monitoring options
src/database/sqlite/sqlite_aclk.c
+107
-41
@@ -76,7 +76,7 @@ static struct aclk_database_cmd aclk_database_deq_cmd(void)
76
77
static void aclk_database_enq_cmd(struct aclk_database_cmd *cmd)
78
{
79
- if(unlikely(!aclk_sync_config.initialized))
79
+ if(unlikely(!__atomic_load_n(&aclk_sync_config.initialized, __ATOMIC_RELAXED)))
80
return;
81
82
struct aclk_database_cmd *t = aral_mallocz(aclk_sync_config.ar);
@@ -505,6 +505,11 @@ struct worker_data {
505
struct aclk_sync_config_s *config;
506
};
507
508
+struct notify_timer_cb_data {
509
+ void *payload;
510
+ struct completion *completion;
511
+};
512
+
513
static void after_do_unregister_node(uv_work_t *req, int status __maybe_unused)
514
{
515
struct worker_data *data = req->data;
@@ -524,16 +529,25 @@ static void do_unregister_node(uv_work_t *req)
529
worker_is_idle();
530
}
531
532
+static void notify_timer_close_callback(uv_handle_t *handle)
533
+{
534
+ struct notify_timer_cb_data *data = handle->data;
535
+ if (data->completion) {
536
+ completion_mark_complete(data->completion);
537
+ }
538
+ freez(data);
539
+}
540
+
541
static void node_update_timer_cb(uv_timer_t *handle)
542
{
529
- struct aclk_sync_cfg_t *ahc = handle->data;
530
- if (unlikely(!ahc))
543
+ struct aclk_sync_cfg_t *aclk_host_config = handle->data;
544
+ if (unlikely(!aclk_host_config))
545
return;
546
533
- RRDHOST *host = ahc->host;
547
+ RRDHOST *host = aclk_host_config->host;
548
549
if(!host || aclk_host_state_update_auto(host))
536
- uv_timer_stop(&ahc->timer);
550
+ uv_timer_stop(&aclk_host_config->timer);
551
}
552
553
static void after_start_alert_push(uv_work_t *req, int status __maybe_unused)
@@ -621,6 +635,8 @@ static void aclk_synchronization_event_loop(void *arg)
635
worker_register_job_name(ACLK_MQTT_WSS_CLIENT_SET, "config mqtt client");
636
worker_register_job_name(ACLK_MQTT_WSS_CLIENT_RESET, "reset mqtt client");
637
worker_register_job_name(ACLK_DATABASE_NODE_UNREGISTER, "unregister node");
638
+ worker_register_job_name(ACLK_CANCEL_NODE_UPDATE_TIMER, "cancel node update timer");
639
+ worker_register_job_name(ACLK_QUEUE_NODE_INFO, "queue node info");
640
641
uv_loop_t *loop = &config->loop;
642
fatal_assert(0 == uv_loop_init(loop));
@@ -640,6 +656,7 @@ static void aclk_synchronization_event_loop(void *arg)
656
netdata_log_info("Starting ACLK synchronization thread with %d parallel query threads", query_thread_count);
657
658
struct worker_data *data;
659
+ struct notify_timer_cb_data *timer_cb_data;
660
aclk_query_t query;
661
662
// This holds queries that need to be executed one by one
@@ -659,6 +676,8 @@ static void aclk_synchronization_event_loop(void *arg)
676
677
while (likely(ACLK_SYNC_SHOULD_BE_RUNNING)) {
678
enum aclk_database_opcode opcode;
679
+ RRDHOST *host;
680
+ struct aclk_sync_cfg_t *aclk_host_config;
681
worker_is_idle();
682
uv_run(loop, UV_RUN_DEFAULT);
683
@@ -695,30 +714,30 @@ static void aclk_synchronization_event_loop(void *arg)
714
/* the command queue was empty, do nothing */
715
break;
716
// NODE STATE
698
- case ACLK_DATABASE_NODE_STATE:;
699
- RRDHOST *host = cmd.param[0];
700
- struct aclk_sync_cfg_t *ahc = host->aclk_config;
701
- if (unlikely(!ahc)) {
717
+ case ACLK_DATABASE_NODE_STATE:
718
+ host = cmd.param[0];
719
+ aclk_host_config = host->aclk_host_config;
720
+ if (unlikely(!aclk_host_config)) {
721
create_aclk_config(host, &host->host_id.uuid, &host->node_id.uuid);
703
- ahc = host->aclk_config;
722
+ aclk_host_config = host->aclk_host_config;
723
}
724
706
- if (ahc) {
725
+ if (aclk_host_config) {
726
uint64_t schedule_time = (uint64_t)(uintptr_t)cmd.param[1];
708
- if (!ahc->timer_initialized) {
709
- int rc = uv_timer_init(loop, &ahc->timer);
727
+ if (!aclk_host_config->timer_initialized) {
728
+ int rc = uv_timer_init(loop, &aclk_host_config->timer);
729
if (!rc) {
711
- ahc->timer_initialized = true;
712
- ahc->timer.data = ahc;
730
+ aclk_host_config->timer_initialized = true;
731
+ aclk_host_config->timer.data = aclk_host_config;
732
}
733
}
734
716
- if (ahc->timer_initialized) {
717
- if (uv_is_active((uv_handle_t *)&ahc->timer))
718
- uv_timer_stop(&ahc->timer);
735
+ if (aclk_host_config->timer_initialized) {
736
+ if (uv_is_active((uv_handle_t *)&aclk_host_config->timer))
737
+ uv_timer_stop(&aclk_host_config->timer);
738
720
- ahc->timer.data = ahc;
721
- int rc = uv_timer_start(&ahc->timer, node_update_timer_cb, schedule_time, 5000);
739
+ aclk_host_config->timer.data = aclk_host_config;
740
+ int rc = uv_timer_start(&aclk_host_config->timer, node_update_timer_cb, schedule_time, 5000);
741
if (!rc)
742
break; // Timer started, exit
743
}
@@ -727,6 +746,31 @@ static void aclk_synchronization_event_loop(void *arg)
746
// This is fallback if timer fails
747
aclk_host_state_update_auto(host);
748
break;
749
+ case ACLK_QUEUE_NODE_INFO:
750
+ host = cmd.param[0];
751
+ bool immediate = (bool)(uintptr_t)cmd.param[1];
752
+ aclk_host_config = host->aclk_host_config;
753
+ if (unlikely(!aclk_host_config)) {
754
+ create_aclk_config(host, &host->host_id.uuid, &host->node_id.uuid);
755
+ aclk_host_config = host->aclk_host_config;
756
+ }
757
+ aclk_host_config->node_info_send_time = (host == localhost ||(void *)(uintptr_t) immediate) ? 1 : now_realtime_sec();
758
+ break;
759
+ case ACLK_CANCEL_NODE_UPDATE_TIMER:
760
+ host = cmd.param[0];
761
+ aclk_host_config = host->aclk_host_config;
762
+ if (!aclk_host_config || !aclk_host_config->timer_initialized)
763
+ break;
764
+ if (uv_is_active((uv_handle_t *)&aclk_host_config->timer))
765
+ uv_timer_stop(&aclk_host_config->timer);
766
+
767
+ aclk_host_config->timer_initialized = false;
768
+ timer_cb_data = mallocz(sizeof(*data));
769
+ timer_cb_data->payload = host;
770
+ timer_cb_data->completion = (struct completion *)cmd.param[1];
771
+ aclk_host_config->timer.data = data;
772
+ uv_close((uv_handle_t *)&aclk_host_config->timer, notify_timer_close_callback);
773
+ break;
774
775
case ACLK_DATABASE_NODE_UNREGISTER:
776
data = mallocz(sizeof(*data));
@@ -739,7 +783,6 @@ static void aclk_synchronization_event_loop(void *arg)
783
freez(data);
784
}
785
break;
742
- // ALERTS
786
case ACLK_DATABASE_PUSH_ALERT_CONFIG:
787
aclk_push_alert_config_event(cmd.param[0], cmd.param[1]);
788
break;
@@ -885,7 +928,7 @@ static void aclk_synchronization_event_loop(void *arg)
928
uv_close((uv_handle_t *)&config->timer_req, NULL);
929
930
uv_close((uv_handle_t *)&config->async, NULL);
888
- uv_walk(loop, libuv_close_callback, NULL);
931
+ uv_walk(loop, libuv_close_callback, notify_timer_close_callback);
932
uv_run(loop, UV_RUN_NOWAIT);
933
934
(void) uv_loop_close(loop);
@@ -932,34 +975,30 @@ static void aclk_initialize_event_loop(void)
975
976
// -------------------------------------------------------------
977
935
-void create_aclk_config(RRDHOST *host __maybe_unused, nd_uuid_t *host_uuid __maybe_unused, nd_uuid_t *node_id __maybe_unused)
978
+void create_aclk_config(RRDHOST *host, nd_uuid_t *host_uuid __maybe_unused, nd_uuid_t *node_id __maybe_unused)
979
{
980
938
- if (!host || host->aclk_config)
981
+ if (!host || host->aclk_host_config)
982
return;
983
941
- struct aclk_sync_cfg_t *wc = callocz(1, sizeof(struct aclk_sync_cfg_t));
984
+ struct aclk_sync_cfg_t *aclk_host_config = callocz(1, sizeof(struct aclk_sync_cfg_t));
985
if (node_id && !uuid_is_null(*node_id))
943
- uuid_unparse_lower(*node_id, wc->node_id);
986
+ uuid_unparse_lower(*node_id, aclk_host_config->node_id);
987
945
- host->aclk_config = wc;
946
- if (node_id && UUIDiszero(host->node_id)) {
947
- uuid_copy(host->node_id.uuid, *node_id);
988
+ struct aclk_sync_cfg_t *expected = NULL;
989
+ if (__atomic_compare_exchange_n(&host->aclk_host_config, &expected, aclk_host_config, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) {
990
+ if (node_id && UUIDiszero(host->node_id))
991
+ uuid_copy(host->node_id.uuid, *node_id);
992
}
949
-
950
- wc->host = host;
951
- wc->stream_alerts = false;
952
- time_t now = now_realtime_sec();
953
- wc->node_info_send_time = (host == localhost || NULL == localhost) ? now - 25 : now;
954
-}
955
-
956
-void destroy_aclk_config(RRDHOST *host)
957
-{
958
- if (!host || !host->aclk_config)
993
+ else {
994
+ freez(aclk_host_config);
995
return;
996
+ }
997
961
- freez(host->aclk_config);
962
- host->aclk_config = NULL;
998
+ aclk_host_config->host = host;
999
+ aclk_host_config->stream_alerts = false;
1000
+ time_t now = now_realtime_sec();
1001
+ aclk_host_config->node_info_send_time = (host == localhost || NULL == localhost) ? now - 25 : now;
1002
}
1003
1004
#define SQL_FETCH_ALL_HOSTS \
@@ -1088,3 +1127,30 @@ void unregister_node(const char *machine_guid)
1127
return;
1128
queue_aclk_sync_cmd(ACLK_DATABASE_NODE_UNREGISTER, strdupz(machine_guid), NULL);
1129
}
1130
+
1131
+void destroy_aclk_config(RRDHOST *host)
1132
+{
1133
+ if (!host)
1134
+ return;
1135
+
1136
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
1137
+ if (!aclk_host_config)
1138
+ return;
1139
+
1140
+ if(likely(__atomic_load_n(&aclk_sync_config.initialized, __ATOMIC_RELAXED))) {
1141
+ struct completion compl;
1142
+ completion_init(&compl);
1143
+
1144
+ queue_aclk_sync_cmd(ACLK_CANCEL_NODE_UPDATE_TIMER, (void *)host, (void *)&compl);
1145
+ completion_wait_for(&compl);
1146
+ completion_destroy(&compl);
1147
+ }
1148
+
1149
+ struct aclk_sync_cfg_t *old_aclk_host_config = __atomic_exchange_n(&host->aclk_host_config, NULL, __ATOMIC_RELAXED);
1150
+ freez(old_aclk_host_config);
1151
+}
1152
+
1153
+void aclk_queue_node_info(RRDHOST *host, bool immediate)
1154
+{
1155
+ queue_aclk_sync_cmd(ACLK_QUEUE_NODE_INFO, (void *)host, (void *)(uintptr_t)immediate);
1156
+}
src/database/sqlite/sqlite_aclk.h
+5
@@ -23,6 +23,9 @@ enum aclk_database_opcode {
23
ACLK_DATABASE_NODE_UNREGISTER,
24
ACLK_MQTT_WSS_CLIENT_SET,
25
ACLK_MQTT_WSS_CLIENT_RESET,
26
+ ACLK_CANCEL_NODE_UPDATE_TIMER,
27
+ ACLK_QUEUE_NODE_INFO,
28
+ ACLK_MQTT_WSS_CLIENT,
29
ACLK_QUERY_EXECUTE,
30
ACLK_QUERY_EXECUTE_SYNC,
31
ACLK_QUERY_BATCH_ADD,
@@ -61,5 +64,7 @@ void aclk_synchronization_shutdown(void);
64
void aclk_push_alert_config(const char *node_id, const char *config_hash);
65
void schedule_node_state_update(RRDHOST *host, uint64_t delay);
66
void unregister_node(const char *machine_guid);
67
+void cancel_node_update_timer(const RRDHOST *host, struct completion *completion);
68
+void aclk_queue_node_info(RRDHOST *host, bool immediate);
69
70
#endif //NETDATA_SQLITE_ACLK_H
src/database/sqlite/sqlite_aclk_alert.c
+50
-43
@@ -504,11 +504,11 @@ static void aclk_push_alert_event(RRDHOST *host, sqlite3_stmt **res, sqlite3_stm
504
505
param = 0;
506
RRDCALC_STATUS status;
507
- struct aclk_sync_cfg_t *wc = host->aclk_config;
507
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
508
while (sqlite3_step_monitored(*res) == SQLITE_ROW) {
509
health_alarm_log_populate(&alarm_log, *res, host, &status);
510
aclk_send_alarm_log_entry(&alarm_log);
511
- wc->alert_count++;
511
+ aclk_host_config->alert_count++;
512
513
last_id = alarm_log.sequence_id;
514
if (first_id == 0)
@@ -651,7 +651,8 @@ bool process_alert_pending_queue(RRDHOST *host)
651
RRDCALC_STATUS new_status = sqlite3_column_int(res, 2);
652
int64_t row = sqlite3_column_int64(res, 3);
653
654
- if (host->aclk_config) {
654
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
655
+ if (aclk_host_config) {
656
int ret = insert_alert_to_submit_queue(host, health_log_id, unique_id, new_status);
657
if (ret == 0)
658
added++;
@@ -686,23 +687,23 @@ void aclk_push_alert_events_for_all_hosts(void)
687
688
rrdhost_flag_clear(host, RRDHOST_FLAG_ACLK_STREAM_ALERTS);
689
689
- struct aclk_sync_cfg_t *wc = host->aclk_config;
690
- if (!wc || false == wc->stream_alerts || rrdhost_flag_check(host, RRDHOST_FLAG_ARCHIVED)) {
690
+ struct aclk_sync_cfg_t *aclk_host_config = host->aclk_host_config;
691
+ if (!aclk_host_config || false == aclk_host_config->stream_alerts || rrdhost_flag_check(host, RRDHOST_FLAG_ARCHIVED)) {
692
(void)process_alert_pending_queue(host);
693
commit_alert_events(host);
694
continue;
695
}
696
696
- if (wc->send_snapshot) {
697
+ if (aclk_host_config->send_snapshot) {
698
rrdhost_flag_set(host, RRDHOST_FLAG_ACLK_STREAM_ALERTS);
698
- if (wc->send_snapshot == 1)
699
+ if (aclk_host_config->send_snapshot == 1)
700
continue;
701
(void)process_alert_pending_queue(host);
702
commit_alert_events(host);
703
rebuild_host_alert_version_table(host);
704
send_alert_snapshot_to_cloud(host);
704
- wc->snapshot_count++;
705
- wc->send_snapshot = 0;
705
+ aclk_host_config->snapshot_count++;
706
+ aclk_host_config->send_snapshot = 0;
707
}
708
else
709
aclk_push_alert_event(host, &res, &res_version);
@@ -717,18 +718,18 @@ void aclk_send_alert_configuration(char *config_hash)
718
if (unlikely(!config_hash))
719
return;
720
720
- struct aclk_sync_cfg_t *wc = localhost->aclk_config;
721
+ struct aclk_sync_cfg_t *aclk_host_config = localhost->aclk_host_config;
722
722
- if (unlikely(!wc))
723
+ if (unlikely(!aclk_host_config))
724
return;
725
726
nd_log(NDLS_ACCESS, NDLP_DEBUG,
727
"ACLK REQ [%s (%s)]: Request to send alert config %s.",
727
- wc->node_id,
728
- wc->host ? rrdhost_hostname(wc->host) : "N/A",
728
+ aclk_host_config->node_id,
729
+ aclk_host_config->host ? rrdhost_hostname(aclk_host_config->host) : "N/A",
730
config_hash);
731
731
- aclk_push_alert_config(wc->node_id, config_hash);
732
+ aclk_push_alert_config(aclk_host_config->node_id, config_hash);
733
}
734
735
#define SQL_SELECT_ALERT_CONFIG \
@@ -740,11 +741,11 @@ void aclk_send_alert_configuration(char *config_hash)
741
void aclk_push_alert_config_event(char *node_id __maybe_unused, char *config_hash __maybe_unused)
742
{
743
sqlite3_stmt *res = NULL;
743
- struct aclk_sync_cfg_t *wc;
744
+ struct aclk_sync_cfg_t *aclk_host_config;
745
746
RRDHOST *host = rrdhost_find_by_node_id(node_id);
747
747
- if (unlikely(!host || !(wc = host->aclk_config))) {
748
+ if (!host || !(aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED))) {
749
freez(config_hash);
750
freez(node_id);
751
return;
@@ -827,13 +828,17 @@ void aclk_push_alert_config_event(char *node_id __maybe_unused, char *config_has
828
param = 0;
829
830
if (likely(p_alarm_config.cfg_hash)) {
830
- nd_log(NDLS_ACCESS, NDLP_DEBUG, "ACLK RES [%s (%s)]: Sent alert config %s.", wc->node_id, wc->host ? rrdhost_hostname(wc->host) : "N/A", config_hash);
831
+ nd_log(NDLS_ACCESS, NDLP_DEBUG, "ACLK RES [%s (%s)]: Sent alert config %s.",
832
+ aclk_host_config->node_id,
833
+ aclk_host_config->host ? rrdhost_hostname(aclk_host_config->host) : "N/A", config_hash);
834
aclk_send_provide_alarm_cfg(&p_alarm_config);
835
freez(p_alarm_config.cfg_hash);
836
destroy_aclk_alarm_configuration(&alarm_config);
837
}
838
else
836
- nd_log(NDLS_ACCESS, NDLP_WARNING, "ACLK STA [%s (%s)]: Alert config for %s not found.", wc->node_id, wc->host ? rrdhost_hostname(wc->host) : "N/A", config_hash);
839
+ nd_log(NDLS_ACCESS, NDLP_WARNING, "ACLK STA [%s (%s)]: Alert config for %s not found.",
840
+ aclk_host_config->node_id,
841
+ aclk_host_config->host ? rrdhost_hostname(aclk_host_config->host) : "N/A", config_hash);
842
843
done:
844
REPORT_BIND_FAIL(res, param);
@@ -868,42 +873,42 @@ done:
873
return version;
874
}
875
871
-static void schedule_alert_snapshot_if_needed(struct aclk_sync_cfg_t *wc, uint64_t cloud_version)
876
+static void schedule_alert_snapshot_if_needed(struct aclk_sync_cfg_t *aclk_host_config, uint64_t cloud_version)
877
{
878
if (cloud_version == 1) {
879
nd_log(
880
NDLS_ACCESS,
881
NDLP_NOTICE,
882
"Cloud requested to skip alert version verification for host \"%s\", node \"%s\"",
878
- rrdhost_hostname(wc->host),
879
- wc->node_id);
883
+ rrdhost_hostname(aclk_host_config->host),
884
+ aclk_host_config->node_id);
885
return;
886
}
887
883
- uint64_t local_version = calculate_node_alert_version(wc->host);
888
+ uint64_t local_version = calculate_node_alert_version(aclk_host_config->host);
889
if (local_version != cloud_version) {
890
nd_log(
891
NDLS_ACCESS,
892
NDLP_NOTICE,
893
"Scheduling alert snapshot for host \"%s\", node \"%s\" (version: cloud %llu, local %llu)",
889
- rrdhost_hostname(wc->host),
890
- wc->node_id,
894
+ rrdhost_hostname(aclk_host_config->host),
895
+ aclk_host_config->node_id,
896
(long long unsigned)cloud_version,
897
(long long unsigned)local_version);
898
894
- wc->send_snapshot = 1;
895
- rrdhost_flag_set(wc->host, RRDHOST_FLAG_ACLK_STREAM_ALERTS);
899
+ aclk_host_config->send_snapshot = 1;
900
+ rrdhost_flag_set(aclk_host_config->host, RRDHOST_FLAG_ACLK_STREAM_ALERTS);
901
}
902
else
903
nd_log(
904
NDLS_ACCESS,
905
NDLP_DEBUG,
906
"Alert check on \"%s\", node \"%s\" (version: cloud %llu, local %llu)",
902
- rrdhost_hostname(wc->host),
903
- wc->node_id,
907
+ rrdhost_hostname(aclk_host_config->host),
908
+ aclk_host_config->node_id,
909
(unsigned long long)cloud_version,
910
(unsigned long long)local_version);
906
- wc->checkpoint_count++;
911
+ aclk_host_config->checkpoint_count++;
912
}
913
914
#define SQL_COUNT_SNAPSHOT_ENTRIES \
@@ -950,10 +955,10 @@ done:
955
#define ALARM_EVENTS_PER_CHUNK 1000
956
void send_alert_snapshot_to_cloud(RRDHOST *host __maybe_unused)
957
{
953
- struct aclk_sync_cfg_t *wc = host->aclk_config;
958
+ struct aclk_sync_cfg_t *aclk_host_config = host->aclk_host_config;
959
960
if (unlikely(!host)) {
956
- nd_log(NDLS_ACCESS, NDLP_WARNING, "AC [%s (N/A)]: Node id not found", wc->node_id);
961
+ nd_log(NDLS_ACCESS, NDLP_WARNING, "AC [%s (N/A)]: Node id not found", aclk_host_config->node_id);
962
return;
963
}
964
@@ -980,7 +985,8 @@ void send_alert_snapshot_to_cloud(RRDHOST *host __maybe_unused)
985
char *snapshot_uuid = &snapshot_uuid_str[0];
986
987
nd_log(NDLS_ACCESS, NDLP_DEBUG,
983
- "ACLK REQ [%s (%s)]: Sending %d alerts snapshot, snapshot_uuid %s", wc->node_id, rrdhost_hostname(host),
988
+ "ACLK REQ [%s (%s)]: Sending %d alerts snapshot, snapshot_uuid %s",
989
+ aclk_host_config->node_id, rrdhost_hostname(host),
990
cnt, snapshot_uuid);
991
992
uint32_t chunks;
@@ -990,13 +996,13 @@ void send_alert_snapshot_to_cloud(RRDHOST *host __maybe_unused)
996
struct alarm_snapshot alarm_snap;
997
struct alarm_log_entry alarm_log;
998
993
- alarm_snap.node_id = wc->node_id;
999
+ alarm_snap.node_id = aclk_host_config->node_id;
1000
alarm_snap.claim_id = claim_id.str;
1001
alarm_snap.snapshot_uuid = snapshot_uuid;
1002
alarm_snap.chunks = chunks;
1003
alarm_snap.chunk = 1;
1004
999
- alarm_log.node_id = wc->node_id;
1005
+ alarm_log.node_id = aclk_host_config->node_id;
1006
alarm_log.claim_id = claim_id.str;
1007
1008
cnt = 0;
@@ -1033,7 +1039,7 @@ void send_alert_snapshot_to_cloud(RRDHOST *host __maybe_unused)
1039
NDLS_ACCESS,
1040
NDLP_DEBUG,
1041
"ACLK REQ [%s (%s)]: Created snapshot %s with %d alerts (version = %llu)",
1036
- wc->node_id,
1042
+ aclk_host_config->node_id,
1043
rrdhost_hostname(host),
1044
snapshot_uuid,
1045
total_count,
@@ -1052,10 +1058,10 @@ void aclk_start_alert_streaming(char *node_id, uint64_t cloud_version)
1058
if (unlikely(!node_id || uuid_parse(node_id, node_uuid)))
1059
return;
1060
1055
- struct aclk_sync_cfg_t *wc;
1061
+ struct aclk_sync_cfg_t *aclk_host_config;
1062
RRDHOST *host = rrdhost_find_by_node_id(node_id);
1063
1058
- if (unlikely(!host || !(wc = host->aclk_config))) {
1064
+ if (!host || !(aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED))) {
1065
nd_log(NDLS_ACCESS, NDLP_NOTICE, "ACLK STA [%s (N/A)]: Ignoring request to stream alert state changes, invalid node.", node_id);
1066
return;
1067
}
@@ -1065,9 +1071,10 @@ void aclk_start_alert_streaming(char *node_id, uint64_t cloud_version)
1071
return;
1072
}
1073
1068
- nd_log(NDLS_ACCESS, NDLP_DEBUG, "ACLK REQ [%s (%s)]: STREAM ALERTS ENABLED", node_id, wc->host ? rrdhost_hostname(wc->host) : "N/A");
1069
- schedule_alert_snapshot_if_needed(wc, cloud_version);
1070
- wc->stream_alerts = true;
1074
+ nd_log(NDLS_ACCESS, NDLP_DEBUG, "ACLK REQ [%s (%s)]: STREAM ALERTS ENABLED", node_id,
1075
+ aclk_host_config->host ? rrdhost_hostname(aclk_host_config->host) : "N/A");
1076
+ schedule_alert_snapshot_if_needed(aclk_host_config, cloud_version);
1077
+ aclk_host_config->stream_alerts = true;
1078
}
1079
1080
// Do checkpoint alert version check
@@ -1086,13 +1093,13 @@ void aclk_alert_version_check(char *node_id, char *claim_id, uint64_t cloud_vers
1093
return;
1094
}
1095
1089
- struct aclk_sync_cfg_t *wc;
1096
+ struct aclk_sync_cfg_t *aclk_host_config;
1097
RRDHOST *host = rrdhost_find_by_node_id(node_id);
1098
1092
- if ((!host || !(wc = host->aclk_config)))
1099
+ if (!host || !(aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED)))
1100
nd_log(NDLS_ACCESS, NDLP_NOTICE,
1101
"ACLK REQ [%s (N/A)]: ALERTS CHECKPOINT VALIDATION REQUEST RECEIVED FOR INVALID NODE",
1102
node_id);
1103
else
1097
- schedule_alert_snapshot_if_needed(wc, cloud_version);
1104
+ schedule_alert_snapshot_if_needed(aclk_host_config, cloud_version);
1105
}
src/database/sqlite/sqlite_aclk_node.c
+17
-15
@@ -25,13 +25,13 @@ DICTIONARY *collectors_from_charts(RRDHOST *host, DICTIONARY *dict) {
25
26
static void build_node_collectors(RRDHOST *host)
27
{
28
- struct aclk_sync_cfg_t *wc = host->aclk_config;
28
+ struct aclk_sync_cfg_t *aclk_host_config = host->aclk_host_config;
29
30
struct update_node_collectors upd_node_collectors;
31
DICTIONARY *dict = dictionary_create(DICT_OPTION_SINGLE_THREADED);
32
33
CLAIM_ID claim_id = claim_id_get();
34
- upd_node_collectors.node_id = wc->node_id;
34
+ upd_node_collectors.node_id = aclk_host_config->node_id;
35
upd_node_collectors.claim_id = claim_id_is_set(claim_id) ? claim_id.str : NULL;
36
37
upd_node_collectors.node_collectors = collectors_from_charts(host, dict);
@@ -41,19 +41,19 @@ static void build_node_collectors(RRDHOST *host)
41
42
nd_log(NDLS_ACCESS, NDLP_DEBUG,
43
"ACLK RES [%s (%s)]: NODE COLLECTORS SENT",
44
- wc->node_id, rrdhost_hostname(host));
44
+ aclk_host_config->node_id, rrdhost_hostname(host));
45
}
46
47
static void build_node_info(RRDHOST *host)
48
{
49
struct update_node_info node_info;
50
51
- struct aclk_sync_cfg_t *wc = host->aclk_config;
51
+ struct aclk_sync_cfg_t *aclk_host_config = host->aclk_host_config;
52
53
CLAIM_ID claim_id = claim_id_get();
54
55
rrd_rdlock();
56
- node_info.node_id = wc->node_id;
56
+ node_info.node_id = aclk_host_config->node_id;
57
node_info.claim_id = claim_id_is_set(claim_id) ? claim_id.str : NULL;
58
node_info.machine_guid = host->machine_guid;
59
node_info.child = (host != localhost);
@@ -85,7 +85,7 @@ static void build_node_info(RRDHOST *host)
85
NDLS_ACCESS,
86
NDLP_DEBUG,
87
"ACLK RES [%s (%s)]: NODE INFO SENT for guid [%s] (%s)",
88
- wc->node_id,
88
+ aclk_host_config->node_id,
89
rrdhost_hostname(host),
90
host->machine_guid,
91
host == localhost ? "parent" : "child");
@@ -94,7 +94,7 @@ static void build_node_info(RRDHOST *host)
94
freez(node_info.node_instance_capabilities);
95
freez(host_version);
96
97
- wc->node_collectors_send = now_realtime_sec();
97
+ aclk_host_config->node_collectors_send = now_realtime_sec();
98
}
99
100
void aclk_check_node_info_and_collectors(void)
@@ -121,8 +121,8 @@ void aclk_check_node_info_and_collectors(void)
121
time_t now = now_realtime_sec();
122
dfe_start_reentrant(rrdhost_root_index, host)
123
{
124
- struct aclk_sync_cfg_t *wc = host->aclk_config;
125
- if (unlikely(!wc))
124
+ struct aclk_sync_cfg_t *aclk_host_config = host->aclk_host_config;
125
+ if (unlikely(!aclk_host_config))
126
continue;
127
128
if (unlikely(rrdhost_flag_check(host, RRDHOST_FLAG_PENDING_CONTEXT_LOAD))) {
@@ -132,7 +132,7 @@ void aclk_check_node_info_and_collectors(void)
132
continue;
133
}
134
135
- if (!wc->node_info_send_time && !wc->node_collectors_send)
135
+ if (!aclk_host_config->node_info_send_time && !aclk_host_config->node_collectors_send)
136
continue;
137
138
if (unlikely(rrdhost_receiver_replicating_charts(host))) {
@@ -156,22 +156,24 @@ void aclk_check_node_info_and_collectors(void)
156
157
bool pp_queue_empty = !(host->rrdctx.pp_queue && dictionary_entries(host->rrdctx.pp_queue));
158
159
- if (!pp_queue_empty && (wc->node_info_send_time || wc->node_collectors_send)) {
159
+ if (!pp_queue_empty && (aclk_host_config->node_info_send_time || aclk_host_config->node_collectors_send)) {
160
context_pp++;
161
context_pp_host = host->hostname;
162
}
163
164
- if (pp_queue_empty && wc->node_info_send_time && wc->node_info_send_time + 30 < now) {
165
- wc->node_info_send_time = 0;
164
+ if (pp_queue_empty && aclk_host_config->node_info_send_time &&
165
+ aclk_host_config->node_info_send_time + 30 < now) {
166
+ aclk_host_config->node_info_send_time = 0;
167
build_node_info(host);
168
schedule_node_state_update(host, 10000);
169
internal_error(true, "ACLK SYNC: Sending node info for %s", rrdhost_hostname(host));
170
}
171
171
- if (pp_queue_empty && wc->node_collectors_send && wc->node_collectors_send + 30 < now) {
172
+ if (pp_queue_empty && aclk_host_config->node_collectors_send &&
173
+ aclk_host_config->node_collectors_send + 30 < now) {
174
build_node_collectors(host);
175
internal_error(true, "ACLK SYNC: Sending collectors for %s", rrdhost_hostname(host));
174
- wc->node_collectors_send = 0;
176
+ aclk_host_config->node_collectors_send = 0;
177
}
178
}
179
dfe_done(host);
src/database/sqlite/sqlite_health.c
+2
-1
@@ -183,7 +183,8 @@ static void insert_alert_queue(
183
184
int rc;
185
186
- if (!host->aclk_config)
186
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
187
+ if (!aclk_host_config)
188
return;
189
190
time_t submit_delay = trigger_time + calculate_delay(old_status, new_status);
src/database/sqlite/sqlite_metadata.c
+3
-3
@@ -279,14 +279,14 @@ static inline void set_host_node_id(RRDHOST *host, nd_uuid_t *node_id)
279
return;
280
}
281
282
- struct aclk_sync_cfg_t *wc = host->aclk_config;
282
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
283
284
uuid_copy(host->node_id.uuid, *node_id);
285
286
- if (unlikely(!wc))
286
+ if (unlikely(!aclk_host_config))
287
create_aclk_config(host, &host->host_id.uuid, node_id);
288
else
289
- uuid_unparse_lower(*node_id, wc->node_id);
289
+ uuid_unparse_lower(*node_id, aclk_host_config->node_id);
290
291
stream_receiver_send_node_and_claim_id_to_child(host);
292
stream_path_node_id_updated(host);
src/health/health_event_loop.c
+5
-5
@@ -283,8 +283,8 @@ static void health_event_loop_for_host(RRDHOST *host, bool apply_hibernation_del
283
284
worker_is_busy(WORKER_HEALTH_JOB_HOST_LOCK);
285
{
286
- struct aclk_sync_cfg_t *wc = host->aclk_config;
287
- if (wc && wc->send_snapshot == 2)
286
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
287
+ if (aclk_host_config && aclk_host_config->send_snapshot == 2)
288
return;
289
}
290
@@ -634,9 +634,9 @@ static void health_event_loop_for_host(RRDHOST *host, bool apply_hibernation_del
634
commit_alert_transitions(host);
635
636
if (!__atomic_load_n(&host->health.pending_transitions, __ATOMIC_RELAXED)) {
637
- struct aclk_sync_cfg_t *wc = host->aclk_config;
638
- if (wc && wc->send_snapshot == 1) {
639
- wc->send_snapshot = 2;
637
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
638
+ if (aclk_host_config && aclk_host_config->send_snapshot == 1) {
639
+ aclk_host_config->send_snapshot = 2;
640
rrdhost_flag_set(host, RRDHOST_FLAG_ACLK_STREAM_ALERTS);
641
} else {
642
worker_is_busy(WORKER_HEALTH_JOB_ALARM_LOG_QUEUE);
src/plugins.d/pluginsd_parser.c
+2
-1
@@ -245,7 +245,8 @@ static inline PARSER_RC pluginsd_host_define_end(char **words __maybe_unused, si
245
246
rrdhost_flag_clear(host, RRDHOST_FLAG_ORPHAN);
247
rrdcontext_host_child_connected(host);
248
- if (host->aclk_config)
248
+ struct aclk_sync_cfg_t *aclk_host_config = __atomic_load_n(&host->aclk_host_config, __ATOMIC_RELAXED);
249
+ if (aclk_host_config)
250
aclk_queue_node_info(host, true);
251
else
252
schedule_node_state_update(host, 100);