Просмотр исходного кода

pipelimit: Cleanup unused pipes

when pipes are unused by a configurable number of timer intervals,
remove them, freeing memory.

(cherry picked from commit 048c928ec68dc82bd628f27bfc9f7901e4c4e9d2)
Alex Hermann 6 лет назад
Родитель
Сommit
07c0b560fa

+ 30 - 0
src/modules/pipelimit/doc/pipelimit_admin.xml

@@ -380,6 +380,36 @@ modparam("pipelimit", "reply_reason", "Limiting")
 		</programlisting>
 		</example>
 	</section>
+	<section id="pipelimit.p.clean_unused">
+		<title><varname>clean_unused</varname> (int)</title>
+		<para>
+		Clean unused pipes afetr this number of timer intervals.
+		</para>
+		<para>
+		<emphasis>
+			Default value is 0 (cleanup disabled).
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>clean_unused</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("pipelimit", "clean_unused", 10)
+...
+</programlisting>
+		</example>
+		<para>
+		This value can be modified at runtime using &sercmd;
+		</para>
+		<example>
+		<title> Set <varname>clean_unused</varname> parameter at runtime </title>
+		<programlisting format="linespecific">
+
+&sercmd; cfg.set_now_int pipelimit clean_unused 10
+
+		</programlisting>
+		</example>
+	</section>
 	</section>
 	<section>
 	<title>Functions</title>

+ 2 - 0
src/modules/pipelimit/pipelimit.c

@@ -111,6 +111,7 @@ static int *load_source = NULL;
 static int pl_timer_interval = PL_TIMER_INTERVAL_DEFAULT;
 static int pl_timer_mode = 0;
 int _pl_cfg_setpoint = 0;        /* desired load, used when reading modparams */
+int pl_clean_unused = 0;
 /* === */
 
 static int pl_load_fetch = 1;
@@ -152,6 +153,7 @@ static param_export_t params[]={
 	{"plp_algorithm_column", PARAM_STR,          &rlp_algorithm_col},
 	{"hash_size",            INT_PARAM,          &pl_hash_size},
 	{"load_fetch",           INT_PARAM,          &pl_load_fetch},
+	{"clean_unused",         INT_PARAM,          &pl_clean_unused},
 
 	{0,0,0}
 };

+ 32 - 3
src/modules/pipelimit/pl_ht.c

@@ -41,6 +41,7 @@
 #include "pl_ht.h"
 
 static rlp_htable_t *_pl_pipes_ht = NULL;
+extern int pl_clean_unused;
 
 str_map_t algo_names[] = {
 	{str_init("NOP"),	PIPE_ALGO_NOP},
@@ -283,6 +284,7 @@ int pl_print_pipes(void)
 			LM_DBG("+++ ++++ counter: %d\n", it->counter);
 			LM_DBG("+++ ++++ last_counter: %d\n", it->last_counter);
 			LM_DBG("+++ ++++ load: %d\n", it->load);
+			LM_DBG("+++ ++++ unused intervals: %d\n", it->unused_intervals);
 			it = it->next;
 		}
 		lock_release(&_pl_pipes_ht->slots[i].lock);
@@ -331,7 +333,7 @@ int pl_pipe_check_feedback_setpoints(int *cfgsp)
 void pl_pipe_timer_update(int interval, int netload)
 {
 	int i;
-	pl_pipe_t *it;
+	pl_pipe_t *it, *it0;
 
 	if(_pl_pipes_ht==NULL)
 		return;
@@ -342,6 +344,31 @@ void pl_pipe_timer_update(int interval, int netload)
 		it = _pl_pipes_ht->slots[i].first;
 		while(it)
 		{
+			if (pl_clean_unused) {
+				if (it->counter > 0) {
+					// used, reset unused intervals counter
+					it->unused_intervals = 0;
+				} else {
+					if (it->unused_intervals >= pl_clean_unused) {
+						// unused for n intervals, delete
+						it0 = it;
+						it = it->next;
+						if(it0->prev==NULL) {
+							_pl_pipes_ht->slots[i].first = it;
+						} else {
+							it0->prev->next = it;
+						}
+						if(it) {
+							it->prev = it0->prev;
+						}
+						_pl_pipes_ht->slots[i].ssize--;
+						pl_pipe_free(it0);
+						continue;
+					} else {
+						it->unused_intervals++;
+					}
+				}
+			}
 			if (it->algo != PIPE_ALGO_NOP) {
 				if( it->algo == PIPE_ALGO_NETWORK ) {
 					it->load = ( netload > it->limit ) ? 1 : -1;
@@ -462,11 +489,13 @@ int rpc_pl_list_pipe(rpc_t *rpc, void *c, pl_pipe_t *it)
 		rpc->fault(c, 500, "Internal pipe structure");
 		return -1;
 	}
-	if(rpc->struct_add(th, "ssdd",
+	if(rpc->struct_add(th, "ssdddd",
 				"name",	it->name.s,
 				"algorithm", algo.s,
 				"limit", it->limit,
-				"counter",  it->counter)<0) {
+				"counter",  it->counter,
+				"last_counter", it->last_counter,
+				"unused_intervals", it->unused_intervals)<0) {
 		rpc->fault(c, 500, "Internal error address list structure");
 		return -1;
 	}

+ 1 - 0
src/modules/pipelimit/pl_ht.h

@@ -45,6 +45,7 @@ typedef struct _pl_pipe
 	int counter;
 	int last_counter;
 	int load;
+	int unused_intervals;
 
     struct _pl_pipe *prev;
     struct _pl_pipe *next;