summaryrefslogtreecommitdiff
path: root/apps/app_queue.c
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2008-05-21 18:31:05 +0000
committerMark Michelson <mmichelson@digium.com>2008-05-21 18:31:05 +0000
commit06a7b4ea4351bffe7544266c7269b91e8fa2a44b (patch)
treee16a42f4e2016b4c1152a9e65db2eac0209acce4 /apps/app_queue.c
parente64aaf24b0e64741b491026646bb0e1eca8c8c6e (diff)
Optimize the update_realtime_member_field function by not having
to query the database for the member and instead using a cached uniqueid. Special thanks to atis for creating this and for keeping it up to date with necessary changes (closes issue #11896) Reported by: atis Patches: realtime_uniqueid_v6.patch uploaded by atis (license 242) Tested by: atis git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@117517 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r--apps/app_queue.c90
1 files changed, 55 insertions, 35 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index eb22bbb13..0e9ed7403 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -384,6 +384,7 @@ struct member {
struct call_queue *lastqueue; /*!< Last queue we received a call */
unsigned int dead:1; /*!< Used to detect members deleted in realtime */
unsigned int delme:1; /*!< Flag to delete entry on reload */
+ char rt_uniqueid[80]; /*!< Unique id of realtime member entry */
};
struct member_interface {
@@ -1309,11 +1310,13 @@ static void queue_set_param(struct call_queue *q, const char *param, const char
* Search for member in queue, if found update penalty/paused state,
* if no memeber exists create one flag it as a RT member and add to queue member list.
*/
-static void rt_handle_member_record(struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str, const char* state_interface)
+static void rt_handle_member_record(struct call_queue *q, char *interface, const char *rt_uniqueid, const char *membername, const char *penalty_str, const char *paused_str, const char* state_interface)
{
- struct member *m, tmpmem;
+ struct member *m;
+ struct ao2_iterator mem_iter;
int penalty = 0;
int paused = 0;
+ int found = 0;
if (penalty_str) {
penalty = atoi(penalty_str);
@@ -1327,32 +1330,39 @@ static void rt_handle_member_record(struct call_queue *q, char *interface, const
paused = 0;
}
- /* Find the member, or the place to put a new one. */
- ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
- m = ao2_find(q->members, &tmpmem, OBJ_POINTER);
-
- /* Create a new one if not found, else update penalty */
- if (!m) {
+ /* Find member by realtime uniqueid and update */
+ mem_iter = ao2_iterator_init(q->members, 0);
+ while ((m = ao2_iterator_next(&mem_iter))) {
+ if (!strcasecmp(m->rt_uniqueid, rt_uniqueid)) {
+ m->dead = 0; /* Do not delete this one. */
+ ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid));
+ if (paused_str)
+ m->paused = paused;
+ if (strcasecmp(state_interface, m->state_interface)) {
+ remove_from_interfaces(m->state_interface);
+ ast_copy_string(m->state_interface, state_interface, sizeof(m->state_interface));
+ add_to_interfaces(m->state_interface);
+ }
+ m->penalty = penalty;
+ found = 1;
+ ao2_ref(m, -1);
+ break;
+ }
+ ao2_ref(m, -1);
+ }
+
+ /* Create a new member */
+ if (!found) {
if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) {
m->dead = 0;
m->realtime = 1;
+ ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid));
add_to_interfaces(m->state_interface);
ao2_link(q->members, m);
ao2_ref(m, -1);
m = NULL;
q->membercount++;
}
- } else {
- m->dead = 0; /* Do not delete this one. */
- if (paused_str)
- m->paused = paused;
- if (strcasecmp(state_interface, m->state_interface)) {
- remove_from_interfaces(m->state_interface);
- ast_copy_string(m->state_interface, state_interface, sizeof(m->state_interface));
- add_to_interfaces(m->state_interface);
- }
- m->penalty = penalty;
- ao2_ref(m, -1);
}
}
@@ -1521,6 +1531,7 @@ static struct call_queue *find_queue_by_name_rt(const char *queuename, struct as
while ((interface = ast_category_browse(member_config, interface))) {
rt_handle_member_record(q, interface,
+ ast_variable_retrieve(member_config, interface, "uniqueid"),
S_OR(ast_variable_retrieve(member_config, interface, "membername"),interface),
ast_variable_retrieve(member_config, interface, "penalty"),
ast_variable_retrieve(member_config, interface, "paused"),
@@ -1590,23 +1601,18 @@ static struct call_queue *load_realtime_queue(const char *queuename)
static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
{
- struct ast_variable *var;
int ret = -1;
- if (!(var = ast_load_realtime("queue_members", "interface", mem->interface, "queue_name", queue_name, NULL)))
- return ret;
- while (var) {
- if (!strcmp(var->name, "uniqueid"))
- break;
- var = var->next;
- }
- if (var && !ast_strlen_zero(var->value)) {
- if ((ast_update_realtime("queue_members", "uniqueid", var->value, field, value, NULL)) > -1)
- ret = 0;
- }
+ if (ast_strlen_zero(mem->rt_uniqueid))
+ return ret;
+
+ if ((ast_update_realtime("queue_members", "uniqueid", mem->rt_uniqueid, field, value, NULL)) > 0)
+ ret = 0;
+
return ret;
}
+
static void update_realtime_members(struct call_queue *q)
{
struct ast_config *member_config = NULL;
@@ -1632,6 +1638,7 @@ static void update_realtime_members(struct call_queue *q)
while ((interface = ast_category_browse(member_config, interface))) {
rt_handle_member_record(q, interface,
+ ast_variable_retrieve(member_config, interface, "uniqueid"),
S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
ast_variable_retrieve(member_config, interface, "penalty"),
ast_variable_retrieve(member_config, interface, "paused"),
@@ -3869,6 +3876,7 @@ static int set_member_paused(const char *queuename, const char *interface, const
struct call_queue *q;
struct member *mem;
struct ao2_iterator queue_iter;
+ int failed;
/* Special event for when all queues are paused - individual events still generated */
/* XXX In all other cases, we use the membername, but since this affects all queues, we cannot */
@@ -3880,18 +3888,26 @@ static int set_member_paused(const char *queuename, const char *interface, const
ao2_lock(q);
if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
if ((mem = interface_exists(q, interface))) {
- found++;
if (mem->paused == paused) {
ast_debug(1, "%spausing already-%spaused queue member %s:%s\n", (paused ? "" : "un"), (paused ? "" : "un"), q->name, interface);
}
+
+ failed = 0;
+ if (mem->realtime) {
+ failed = update_realtime_member_field(mem, q->name, "paused", paused ? "1" : "0");
+ }
+
+ if (failed) {
+ ast_log(LOG_WARNING, "Failed %spausing realtime queue member %s:%s\n", (paused ? "" : "un"), q->name, interface);
+ ao2_ref(mem, -1);
+ continue;
+ }
+ found++;
mem->paused = paused;
if (queue_persistent_members)
dump_queue_members(q);
- if (mem->realtime)
- update_realtime_member_field(mem, q->name, "paused", paused ? "1" : "0");
-
ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", S_OR(reason, ""));
if (!ast_strlen_zero(reason)) {
@@ -3915,6 +3931,10 @@ static int set_member_paused(const char *queuename, const char *interface, const
}
ao2_unlock(q);
queue_unref(q);
+
+ if (!ast_strlen_zero(queuename) && found) {
+ break;
+ }
}
return found ? RESULT_SUCCESS : RESULT_FAILURE;