@cryptotaxi247 / netdata-1 / commits / 83bc63694

Dynamic memory cleanup for MongoDB exporting connector (#9103)

Vladimir Kobal committed May 21, 2020 at 10:11 UTC 83bc63694a79dc25dda26723bed8cb12e700da50
2 files changed +80 -46
exporting/exporting_engine.c
+1
@@ -30,6 +30,7 @@ static void exporting_main_cleanup(void *ptr)
30 if (!instance->exited) {
31 found++;
32 info("stopping worker for instance %s", instance->config.name);
33 + uv_mutex_unlock(&instance->mutex);
34 uv_cond_signal(&instance->cond_var);
35 } else
36 info("found stopped worker for instance %s", instance->config.name);
exporting/mongodb/mongodb.c
+79 -46
@@ -79,22 +79,6 @@ int mongodb_init(struct instance *instance)
79 return 0;
80 }
81
82 -/**
83 - * Clean a MongoDB connector instance up
84 - *
85 - * @param instance an instance data structure.
86 - */
87 -void mongodb_cleanup(struct instance *instance)
88 -{
89 - struct mongodb_specific_data *connector_specific_data =
90 - (struct mongodb_specific_data *)instance->connector_specific_data;
91 -
92 - mongoc_collection_destroy(connector_specific_data->collection);
93 - mongoc_client_destroy(connector_specific_data->client);
94 -
95 - return;
96 -}
97 -
82 /**
83 * Initialize a MongoDB connector instance
84 *
@@ -237,6 +221,51 @@ int format_batch_mongodb(struct instance *instance)
221 return 0;
222 }
223
224 +/**
225 + * Clean a MongoDB connector instance up
226 + *
227 + * @param instance an instance data structure.
228 + */
229 +void mongodb_cleanup(struct instance *instance)
230 +{
231 + info("EXPORTING: cleaning up instance %s ...", instance->config.name);
232 +
233 + struct mongodb_specific_data *connector_specific_data =
234 + (struct mongodb_specific_data *)instance->connector_specific_data;
235 +
236 + mongoc_collection_destroy(connector_specific_data->collection);
237 + mongoc_client_destroy(connector_specific_data->client);
238 + if (instance->engine->mongoc_initialized) {
239 + mongoc_cleanup();
240 + instance->engine->mongoc_initialized = 0;
241 + }
242 +
243 + buffer_free(instance->buffer);
244 +
245 + struct bson_buffer *next_buffer = connector_specific_data->first_buffer;
246 + for (int i = 0; i < instance->config.buffer_on_failures; i++) {
247 + struct bson_buffer *current_buffer = next_buffer;
248 + next_buffer = next_buffer->next;
249 +
250 + if (current_buffer->insert)
251 + free_bson(current_buffer->insert, current_buffer->documents_inserted);
252 + freez(current_buffer);
253 + }
254 +
255 + freez(connector_specific_data);
256 +
257 + struct mongodb_specific_config *connector_specific_config =
258 + (struct mongodb_specific_config *)instance->config.connector_specific_config;
259 + freez(connector_specific_config->database);
260 + freez(connector_specific_config->collection);
261 + freez(connector_specific_config);
262 +
263 + info("EXPORTING: instance %s exited", instance->config.name);
264 + instance->exited = 1;
265 +
266 + return;
267 +}
268 +
269 /**
270 * MongoDB connector worker
271 *
@@ -251,12 +280,17 @@ void mongodb_connector_worker(void *instance_p)
280 struct mongodb_specific_data *connector_specific_data =
281 (struct mongodb_specific_data *)instance->connector_specific_data;
282
254 - while (!netdata_exit) {
283 + while (!instance->engine->exit) {
284 struct stats *stats = &instance->stats;
285
286 uv_mutex_lock(&instance->mutex);
287 uv_cond_wait(&instance->cond_var, &instance->mutex);
288
289 + if (unlikely(instance->engine->exit)) {
290 + uv_mutex_unlock(&instance->mutex);
291 + break;
292 + }
293 +
294 // reset the monitoring chart counters
295 stats->received_bytes =
296 stats->sent_bytes =
@@ -293,38 +327,37 @@ void mongodb_connector_worker(void *instance_p)
327 connector_specific_config->collection,
328 data_size);
329
296 - if (unlikely(documents_inserted == 0))
297 - continue;
298 -
299 - bson_error_t bson_error;
300 - if (likely(mongoc_collection_insert_many(
301 - connector_specific_data->collection,
302 - (const bson_t **)insert,
303 - documents_inserted,
304 - NULL,
305 - NULL,
306 - &bson_error))) {
307 - stats->sent_metrics = documents_inserted;
308 - stats->sent_bytes += data_size;
309 - stats->transmission_successes++;
310 - stats->receptions++;
311 - } else {
312 - // oops! we couldn't send (all or some of the) data
313 - error("EXPORTING: %s", bson_error.message);
314 - error(
315 - "EXPORTING: failed to write data to the database '%s'. "
316 - "Willing to write %zu bytes, wrote %zu bytes.",
317 - instance->config.destination, data_size, 0UL);
318 -
319 - stats->transmission_failures++;
320 - stats->data_lost_events++;
321 - stats->lost_bytes += buffered_bytes;
322 - stats->lost_metrics += documents_inserted;
330 + if (likely(documents_inserted != 0)) {
331 + bson_error_t bson_error;
332 + if (likely(mongoc_collection_insert_many(
333 + connector_specific_data->collection,
334 + (const bson_t **)insert,
335 + documents_inserted,
336 + NULL,
337 + NULL,
338 + &bson_error))) {
339 + stats->sent_metrics = documents_inserted;
340 + stats->sent_bytes += data_size;
341 + stats->transmission_successes++;
342 + stats->receptions++;
343 + } else {
344 + // oops! we couldn't send (all or some of the) data
345 + error("EXPORTING: %s", bson_error.message);
346 + error(
347 + "EXPORTING: failed to write data to the database '%s'. "
348 + "Willing to write %zu bytes, wrote %zu bytes.",
349 + instance->config.destination, data_size, 0UL);
350 +
351 + stats->transmission_failures++;
352 + stats->data_lost_events++;
353 + stats->lost_bytes += buffered_bytes;
354 + stats->lost_metrics += documents_inserted;
355 + }
356 }
357
358 free_bson(insert, documents_inserted);
359
327 - if (unlikely(netdata_exit))
360 + if (unlikely(instance->engine->exit))
361 break;
362
363 uv_mutex_lock(&instance->mutex);
@@ -341,7 +374,7 @@ void mongodb_connector_worker(void *instance_p)
374 uv_mutex_unlock(&instance->mutex);
375
376 #ifdef UNIT_TESTING
344 - break;
377 + return;
378 #endif
379 }
380