mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-23 22:45:39 +00:00
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
This commit is contained in:
@@ -384,6 +384,7 @@ struct member {
|
|||||||
struct call_queue *lastqueue; /*!< Last queue we received a call */
|
struct call_queue *lastqueue; /*!< Last queue we received a call */
|
||||||
unsigned int dead:1; /*!< Used to detect members deleted in realtime */
|
unsigned int dead:1; /*!< Used to detect members deleted in realtime */
|
||||||
unsigned int delme:1; /*!< Flag to delete entry on reload */
|
unsigned int delme:1; /*!< Flag to delete entry on reload */
|
||||||
|
char rt_uniqueid[80]; /*!< Unique id of realtime member entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct member_interface {
|
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,
|
* 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.
|
* 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 penalty = 0;
|
||||||
int paused = 0;
|
int paused = 0;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
if (penalty_str) {
|
if (penalty_str) {
|
||||||
penalty = atoi(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;
|
paused = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the member, or the place to put a new one. */
|
/* Find member by realtime uniqueid and update */
|
||||||
ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
|
mem_iter = ao2_iterator_init(q->members, 0);
|
||||||
m = ao2_find(q->members, &tmpmem, OBJ_POINTER);
|
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 one if not found, else update penalty */
|
/* Create a new member */
|
||||||
if (!m) {
|
if (!found) {
|
||||||
if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) {
|
if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) {
|
||||||
m->dead = 0;
|
m->dead = 0;
|
||||||
m->realtime = 1;
|
m->realtime = 1;
|
||||||
|
ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid));
|
||||||
add_to_interfaces(m->state_interface);
|
add_to_interfaces(m->state_interface);
|
||||||
ao2_link(q->members, m);
|
ao2_link(q->members, m);
|
||||||
ao2_ref(m, -1);
|
ao2_ref(m, -1);
|
||||||
m = NULL;
|
m = NULL;
|
||||||
q->membercount++;
|
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))) {
|
while ((interface = ast_category_browse(member_config, interface))) {
|
||||||
rt_handle_member_record(q, interface,
|
rt_handle_member_record(q, interface,
|
||||||
|
ast_variable_retrieve(member_config, interface, "uniqueid"),
|
||||||
S_OR(ast_variable_retrieve(member_config, interface, "membername"),interface),
|
S_OR(ast_variable_retrieve(member_config, interface, "membername"),interface),
|
||||||
ast_variable_retrieve(member_config, interface, "penalty"),
|
ast_variable_retrieve(member_config, interface, "penalty"),
|
||||||
ast_variable_retrieve(member_config, interface, "paused"),
|
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)
|
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;
|
int ret = -1;
|
||||||
|
|
||||||
if (!(var = ast_load_realtime("queue_members", "interface", mem->interface, "queue_name", queue_name, NULL)))
|
if (ast_strlen_zero(mem->rt_uniqueid))
|
||||||
return ret;
|
return ret;
|
||||||
while (var) {
|
|
||||||
if (!strcmp(var->name, "uniqueid"))
|
if ((ast_update_realtime("queue_members", "uniqueid", mem->rt_uniqueid, field, value, NULL)) > 0)
|
||||||
break;
|
ret = 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void update_realtime_members(struct call_queue *q)
|
static void update_realtime_members(struct call_queue *q)
|
||||||
{
|
{
|
||||||
struct ast_config *member_config = NULL;
|
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))) {
|
while ((interface = ast_category_browse(member_config, interface))) {
|
||||||
rt_handle_member_record(q, interface,
|
rt_handle_member_record(q, interface,
|
||||||
|
ast_variable_retrieve(member_config, interface, "uniqueid"),
|
||||||
S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
|
S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
|
||||||
ast_variable_retrieve(member_config, interface, "penalty"),
|
ast_variable_retrieve(member_config, interface, "penalty"),
|
||||||
ast_variable_retrieve(member_config, interface, "paused"),
|
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 call_queue *q;
|
||||||
struct member *mem;
|
struct member *mem;
|
||||||
struct ao2_iterator queue_iter;
|
struct ao2_iterator queue_iter;
|
||||||
|
int failed;
|
||||||
|
|
||||||
/* Special event for when all queues are paused - individual events still generated */
|
/* 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 */
|
/* 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);
|
ao2_lock(q);
|
||||||
if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
|
if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
|
||||||
if ((mem = interface_exists(q, interface))) {
|
if ((mem = interface_exists(q, interface))) {
|
||||||
found++;
|
|
||||||
if (mem->paused == paused) {
|
if (mem->paused == paused) {
|
||||||
ast_debug(1, "%spausing already-%spaused queue member %s:%s\n", (paused ? "" : "un"), (paused ? "" : "un"), q->name, interface);
|
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;
|
mem->paused = paused;
|
||||||
|
|
||||||
if (queue_persistent_members)
|
if (queue_persistent_members)
|
||||||
dump_queue_members(q);
|
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, ""));
|
ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", S_OR(reason, ""));
|
||||||
|
|
||||||
if (!ast_strlen_zero(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);
|
ao2_unlock(q);
|
||||||
queue_unref(q);
|
queue_unref(q);
|
||||||
|
|
||||||
|
if (!ast_strlen_zero(queuename) && found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return found ? RESULT_SUCCESS : RESULT_FAILURE;
|
return found ? RESULT_SUCCESS : RESULT_FAILURE;
|
||||||
|
Reference in New Issue
Block a user