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
1.6.1
Mark Michelson 17 years ago
parent e64aaf24b0
commit 06a7b4ea43

@ -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;

Loading…
Cancel
Save