[svn-commits] mmichelson: trunk r117517 - /trunk/apps/app_queue.c
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Wed May 21 13:31:05 CDT 2008
Author: mmichelson
Date: Wed May 21 13:31:05 2008
New Revision: 117517
URL: http://svn.digium.com/view/asterisk?view=rev&rev=117517
Log:
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
Modified:
trunk/apps/app_queue.c
Modified: trunk/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_queue.c?view=diff&rev=117517&r1=117516&r2=117517
==============================================================================
--- trunk/apps/app_queue.c (original)
+++ trunk/apps/app_queue.c Wed May 21 13:31:05 2008
@@ -384,6 +384,7 @@
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 @@
* 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)
-{
- struct member *m, tmpmem;
+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;
+ 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 @@
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 @@
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,22 +1601,17 @@
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)
{
@@ -1632,6 +1638,7 @@
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 @@
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,17 +3888,25 @@
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, ""));
@@ -3915,6 +3931,10 @@
}
ao2_unlock(q);
queue_unref(q);
+
+ if (!ast_strlen_zero(queuename) && found) {
+ break;
+ }
}
return found ? RESULT_SUCCESS : RESULT_FAILURE;
More information about the svn-commits
mailing list