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