[asterisk-commits] mmichelson: branch mmichelson/queue-penalty r94343 - /team/mmichelson/queue-p...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Dec 20 17:30:10 CST 2007


Author: mmichelson
Date: Thu Dec 20 17:30:10 2007
New Revision: 94343

URL: http://svn.digium.com/view/asterisk?view=rev&rev=94343
Log:
A few changes

1. Moved the reloading of queuerules to a separate function. This allowed me to...
2. Add a CLI command to reload queuerules (without having to reload the entire queue module)
3. Changed the CLI commands that to refer to queue "rules" instead of queue "rule"
4. Moved the logic to update a queue_ent's penalty_rule to a function so that it could be called
by both wait_our_turn and queue_exec. Less code duplication is a good thing.



Modified:
    team/mmichelson/queue-penalty/apps/app_queue.c

Modified: team/mmichelson/queue-penalty/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue-penalty/apps/app_queue.c?view=diff&rev=94343&r1=94342&r2=94343
==============================================================================
--- team/mmichelson/queue-penalty/apps/app_queue.c (original)
+++ team/mmichelson/queue-penalty/apps/app_queue.c Thu Dec 20 17:30:10 2007
@@ -1017,7 +1017,6 @@
 	}
 
 	contentdup = ast_strdupa(content);
-	ast_log(LOG_DEBUG, "Analyzing entry %s on line %d...\n", contentdup, linenum);
 	
 	if (!(maxstr = strchr(contentdup, ','))) {
 		ast_log(LOG_WARNING, "Improperly formatted penaltychange rule at line %d. Ignoring.\n", linenum);
@@ -1055,8 +1054,9 @@
 		rule->min_relative = 1;
 
 	/*We have the rule made, now we need to insert it where it belongs*/
+	AST_LIST_LOCK(&rule_lists);
 	AST_LIST_TRAVERSE(&rule_lists, rl_iter, list){
-		if(strcasecmp(rl_iter->name, list_name))
+		if (strcasecmp(rl_iter->name, list_name))
 			continue;
 
 		AST_LIST_TRAVERSE_SAFE_BEGIN(&rl_iter->rules, rule_iter, list) {
@@ -1072,6 +1072,7 @@
 			AST_LIST_INSERT_TAIL(&rl_iter->rules, rule, list);
 		}
 	}
+	AST_LIST_UNLOCK(&rule_lists);
 
 	return 0;
 }
@@ -2606,6 +2607,28 @@
 	return res;
 }
 
+static void update_qe_rule(struct queue_ent *qe)
+{
+	int max_penalty = qe->pr->max_relative ? qe->max_penalty + qe->pr->max_value : qe->pr->max_value;
+	int min_penalty = qe->pr->min_relative ? qe->min_penalty + qe->pr->min_value : qe->pr->min_value;
+	char max_penalty_str[20], min_penalty_str[20]; 
+	/* a relative change to the penalty could put it below 0 */
+	if (max_penalty < 0)
+		max_penalty = 0;
+	if (min_penalty < 0)
+		min_penalty = 0;
+	if (min_penalty > max_penalty)
+		min_penalty = max_penalty;
+	snprintf(max_penalty_str, sizeof(max_penalty_str) - 1, "%d", max_penalty);
+	snprintf(min_penalty_str, sizeof(min_penalty_str) - 1, "%d", min_penalty);
+	pbx_builtin_setvar_helper(qe->chan, "QUEUE_MAX_PENALTY", max_penalty_str);
+	pbx_builtin_setvar_helper(qe->chan, "QUEUE_MIN_PENALTY", min_penalty_str);
+	qe->max_penalty = max_penalty;
+	qe->min_penalty = min_penalty;
+	ast_debug(3, "Setting max penalty to %d and min penalty to %d for caller %s since %d seconds have elapsed\n", qe->max_penalty, qe->min_penalty, qe->chan->name, qe->pr->time);
+	qe->pr = AST_LIST_NEXT(qe->pr, list);
+}
+
 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
 {
 	int res = 0;
@@ -2659,24 +2682,7 @@
 		
 		/* see if we need to move to the next penalty level for this queue */
 		while (qe->pr && ((time(NULL) - qe->start) > qe->pr->time)) {
-			int max_penalty = qe->pr->max_relative ? qe->max_penalty + qe->pr->max_value : qe->pr->max_value;
-			int min_penalty = qe->pr->min_relative ? qe->min_penalty + qe->pr->min_value : qe->pr->min_value;
-			char max_penalty_str[12], min_penalty_str[12]; /*XXX Will change this idiom and probably optimize things once everything is running */
-			/* a relative change to the penalty could put it below 0 */
-			if (max_penalty < 0)
-				max_penalty = 0;
-			if (min_penalty < 0)
-				min_penalty = 0;
-			if (min_penalty > max_penalty)
-				min_penalty = max_penalty;
-			snprintf(max_penalty_str, sizeof(max_penalty_str) - 1, "%d", max_penalty);
-			snprintf(min_penalty_str, sizeof(min_penalty_str) - 1, "%d", min_penalty);
-			pbx_builtin_setvar_helper(qe->chan, "QUEUE_MAX_PENALTY", max_penalty_str);
-			pbx_builtin_setvar_helper(qe->chan, "QUEUE_MIN_PENALTY", min_penalty_str);
-			qe->max_penalty = max_penalty;
-			qe->min_penalty = min_penalty;
-			ast_log(LOG_DEBUG, "Set max penalty to %d and min penalty to %d for caller %s\n", qe->max_penalty, qe->min_penalty, qe->chan->name);
-			qe->pr = AST_LIST_NEXT(qe->pr, list);
+			update_qe_rule(qe);
 		}
 
 		/* Wait a second before checking again */
@@ -4082,7 +4088,7 @@
 	const char *tmp = ast_strlen_zero(rulename) ? qe->parent->defaultrule : rulename;
 	AST_LIST_LOCK(&rule_lists);
 	AST_LIST_TRAVERSE(&rule_lists, rl_iter, list) {
-		if(!strcasecmp(rl_iter->name, tmp))
+		if (!strcasecmp(rl_iter->name, tmp))
 			break;
 	}
 	if (rl_iter) {
@@ -4310,24 +4316,7 @@
 
 			/* see if we need to move to the next penalty level for this queue */
 			while (qe.pr && ((time(NULL) - qe.start) > qe.pr->time)) {
-				char max_penalty_str[12], min_penalty_str[12]; /*XXX Will change this idiom and probably optimize things once everything is running */
-				max_penalty = qe.pr->max_relative ? qe.max_penalty + qe.pr->max_value : qe.pr->max_value;
-				min_penalty = qe.pr->min_relative ? qe.min_penalty + qe.pr->min_value : qe.pr->min_value;
-				/* A relative change could put the max_penalty below 0 */
-				if (max_penalty < 0)
-					max_penalty = 0;
-				if (min_penalty < 0)
-					min_penalty = 0;
-				if (min_penalty > max_penalty)
-					min_penalty = max_penalty;
-				snprintf(max_penalty_str, sizeof(max_penalty_str) - 1, "%d", max_penalty);
-				snprintf(min_penalty_str, sizeof(min_penalty_str) - 1, "%d", min_penalty);
-				pbx_builtin_setvar_helper(qe.chan, "QUEUE_MAX_PENALTY", max_penalty_str);
-				pbx_builtin_setvar_helper(qe.chan, "QUEUE_MAX_PENALTY", min_penalty_str);
-				qe.max_penalty = max_penalty;
-				qe.min_penalty = min_penalty;
-				ast_log(LOG_DEBUG, "Changed the max penalty to %d and the min penalty to %d for caller %s since %d seconds have elapsed\n", qe.max_penalty, qe.min_penalty, qe.chan->name, qe.pr->time);
-				qe.pr = AST_LIST_NEXT(qe.pr, list);
+				update_qe_rule(&qe);
 			}
 
 			/* If using dynamic realtime members, we should regenerate the member list for this queue */
@@ -4731,6 +4720,45 @@
 	.write = queue_function_memberpenalty_write,
 };
 
+static int reload_queue_rules(int reload)
+{
+	struct ast_config *cfg;
+	struct rule_list *rl_iter, *new_rl;
+	struct penalty_rule *pr_iter;
+	char *rulecat = NULL;
+	struct ast_variable *rulevar = NULL;
+	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+	
+	if (!(cfg = ast_config_load("queuerules.conf", config_flags))) {
+		ast_log(LOG_NOTICE, "No queuerules.conf file found, queues will not follow penalty rules\n");
+	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
+		ast_log(LOG_NOTICE, "queuerules.conf has not changed since it was last loaded. Not taking any action.\n");
+		return AST_MODULE_LOAD_SUCCESS;
+	} else {
+		AST_LIST_LOCK(&rule_lists);
+		while ((rl_iter = AST_LIST_REMOVE_HEAD(&rule_lists, list))) {
+			while ((pr_iter = AST_LIST_REMOVE_HEAD(&rl_iter->rules, list)))
+				ast_free(pr_iter);
+			ast_free(rl_iter);
+		}
+		while ((rulecat = ast_category_browse(cfg, rulecat))) {
+			if (!(new_rl = ast_calloc(1, sizeof(*new_rl)))) {
+				ast_log(LOG_ERROR, "Memory allocation error while loading queuerules.conf! Aborting!\n");
+				AST_LIST_UNLOCK(&rule_lists);
+				return AST_MODULE_LOAD_FAILURE;
+			} else {
+				ast_copy_string(new_rl->name, rulecat, sizeof(new_rl->name));
+				AST_LIST_INSERT_TAIL(&rule_lists, new_rl, list);
+				for (rulevar = ast_variable_browse(cfg, rulecat); rulevar; rulevar = rulevar->next)
+					insert_penaltychange(new_rl->name, rulevar->value, rulevar->lineno);
+			}
+		}
+		AST_LIST_UNLOCK(&rule_lists);
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
 
 static int reload_queues(int reload)
 {
@@ -4740,8 +4768,6 @@
 	struct ast_variable *var;
 	struct member *cur, *newm;
 	struct ao2_iterator mem_iter;
-	struct penalty_rule *pr_iter;
-	struct rule_list *rl_iter;
 	int new;
 	const char *general_val = NULL;
 	char parse[80];
@@ -4757,31 +4783,9 @@
 	);
 
 	/*First things first. Let's load queuerules.conf*/
-	AST_LIST_LOCK(&rule_lists);
-	while((rl_iter = AST_LIST_REMOVE_HEAD(&rule_lists, list))) {
-		while ((pr_iter = AST_LIST_REMOVE_HEAD(&rl_iter->rules, list)))
-			ast_free(pr_iter);
-		ast_free(rl_iter);
-	}
-	if (!(cfg = ast_config_load("queuerules.conf", config_flags))) {
-		ast_log(LOG_NOTICE, "No queuerules.conf file found, queues will not follow penalty rules\n");
-	} else {
-		char *rulecat = NULL;
-		struct ast_variable *rulevar = NULL;
-		while((rulecat = ast_category_browse(cfg, rulecat))) {
-			struct rule_list *rl = ast_calloc(1, sizeof(*rl));
-			if (!rl){
-				/*Handle allocation failure*/
-			} else {
-				ast_copy_string(rl->name, rulecat, sizeof(rl->name));
-				AST_LIST_INSERT_TAIL(&rule_lists, rl, list);
-				for (rulevar = ast_variable_browse(cfg, rulecat); rulevar; rulevar = rulevar->next)
-					insert_penaltychange(rl->name, rulevar->value, rulevar->lineno);
-			}
-		}
-	}
-	AST_LIST_UNLOCK(&rule_lists);
-	
+	if (reload_queue_rules(reload) == AST_MODULE_LOAD_FAILURE)
+		return AST_MODULE_LOAD_FAILURE;
+		
 	if (!(cfg = ast_config_load("queues.conf", config_flags))) {
 		ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n");
 		return 0;
@@ -5131,12 +5135,12 @@
 
 	AST_LIST_LOCK(&rule_lists);
 	AST_LIST_TRAVERSE(&rule_lists, rl_iter, list) {
-		if(ast_strlen_zero(rule) || !strcasecmp(rule, rl_iter->name)) {
+		if (ast_strlen_zero(rule) || !strcasecmp(rule, rl_iter->name)) {
 			astman_append(s, "RuleList: %s\r\n", rl_iter->name);
 			AST_LIST_TRAVERSE(&rl_iter->rules, pr_iter, list) {
 				astman_append(s, "Rule: %d,%s%d,%s%d\r\n", pr_iter->time, pr_iter->max_relative && pr_iter->max_value >= 0 ? "+" : "", pr_iter->max_value, pr_iter->min_relative && pr_iter->min_value >= 0 ? "+" : "", pr_iter->min_value );
 			}
-			if(!ast_strlen_zero(rule))
+			if (!ast_strlen_zero(rule))
 				break;
 		}
 	}
@@ -5810,9 +5814,9 @@
 	struct penalty_rule *pr_iter;
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "queue rule show";
+		e->command = "queue rules show";
 		e->usage =
-		"Usage: queue rule show [rulename]\n"
+		"Usage: queue rules show [rulename]\n"
 		"Show the list of rules associated with rulename. If no\n"
 		"rulename is specified, list all rules defined in queuerules.conf\n";
 		return NULL;
@@ -5837,6 +5841,22 @@
 	return CLI_SUCCESS; 
 }
 
+static char *handle_queue_rule_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+		case CLI_INIT:
+			e->command = "queue rules reload";
+			e->usage = 
+				"Usage: queue rule reload\n"
+				"Reloads rules defined in queuerules.conf\n";
+			return NULL;
+		case CLI_GENERATE:
+			return NULL;
+	}
+	reload_queue_rules(1);
+	return CLI_SUCCESS;
+}
+
 static const char qpm_cmd_usage[] = 
 "Usage: queue pause member <channel> in <queue> reason <reason>\n";
 
@@ -5853,6 +5873,7 @@
 	AST_CLI_DEFINE(handle_queue_pause_member, "Pause or unpause a queue member"),
 	AST_CLI_DEFINE(handle_queue_set_member_penalty, "Set penalty for a channel of a specified queue"),
 	AST_CLI_DEFINE(handle_queue_rule_show, "Show the rules defined in queuerules.conf"),
+	AST_CLI_DEFINE(handle_queue_rule_reload, "Reload the rules defined in queuerules.conf"),
 };
 
 static int unload_module(void)




More information about the asterisk-commits mailing list