From 0af2a50d1e3c68b1f845c09671ff800fa4ca99b9 Mon Sep 17 00:00:00 2001
From: Lukasz Kotasa <lukasz.kotasa@iopsys.eu>
Date: Tue, 31 Oct 2023 10:42:46 +0100
Subject: [PATCH] limit memory consumption after each call made

After each call, stasis message is created and stored
in memory. This can cause big memory consumption
if many calls are processed. We re-use `csv_max_row`
config (see below) to control how many entries can
be cached in stasis_cache.

/etc/config/asterisk

config cdr 'cdr_options'
  option csv_max_row '100'
---
 main/stasis_cache.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/main/stasis_cache.c b/main/stasis_cache.c
index 55a364786d..9f6163a75c 100644
--- a/main/stasis_cache.c
+++ b/main/stasis_cache.c
@@ -30,6 +30,7 @@
 #include "asterisk.h"
 
 #include "asterisk/astobj2.h"
+#include "asterisk/config.h"
 #include "asterisk/hashtab.h"
 #include "asterisk/stasis_internal.h"
 #include "asterisk/stasis.h"
@@ -42,6 +43,10 @@
 #define NUM_CACHE_BUCKETS 563
 #endif
 
+/// max count for stasis elements cached is synched with maxrow from cdr
+static int maxrow = 100;
+static const char config[] = "cdr.conf";
+
 /*! \internal */
 struct stasis_cache {
 	struct ao2_container *entries;
@@ -213,6 +218,9 @@ static struct stasis_cache_entry *cache_entry_create(struct stasis_message_type
 {
 	struct stasis_cache_entry *entry;
 	int is_remote;
+	struct ast_config *cfg;
+	struct ast_variable *v;
+	struct ast_flags config_flags = { 0 };
 
 	ast_assert(id != NULL);
 	ast_assert(snapshot != NULL);
@@ -260,6 +268,20 @@ static struct stasis_cache_entry *cache_entry_create(struct stasis_message_type
 	}
 	ao2_bump(snapshot);
 
+	// get maxrow from cdr.conf
+	if (!(cfg = ast_config_load(config, config_flags))) {
+		ast_log(LOG_WARNING, "unable to load config: %s\n", config);
+	}
+	v = ast_variable_browse(cfg, "csv");
+	if (v) {
+		for (; v; v = v->next) {
+			if (!strcasecmp(v->name, "maxrow")) {
+				maxrow = atoi(v->value);
+			}
+		}
+	}
+	ast_config_destroy(cfg);
+
 	return entry;
 }
 
@@ -533,7 +555,10 @@ static struct cache_put_snapshots cache_put(struct stasis_cache *cache,
 		/* Insert into the cache */
 		cached_entry = cache_entry_create(type, id, new_snapshot);
 		if (cached_entry) {
-			ao2_link_flags(cache->entries, cached_entry, OBJ_NOLOCK);
+			if (ao2_container_count(cache->entries) >= maxrow)
+				ast_log(LOG_VERBOSE, "reached max capacity for cache entries: %d out of %d used\n", ao2_container_count(cache->entries), maxrow);
+			else
+				ao2_link_flags(cache->entries, cached_entry, OBJ_NOLOCK);
 		}
 	}
 
-- 
GitLab