[asterisk-dev] [asterisk-commits] mmichelson: trunk r117517 - /trunk/apps/app_queue.c
Atis Lezdins
atis at iq-labs.net
Thu May 22 02:54:21 CDT 2008
On Wed, May 21, 2008 at 9:31 PM, SVN commits to the Asterisk project
<asterisk-commits at lists.digium.com> wrote:
> 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;
> + }
Oops, this should be:
if (!ast_strlen_zero(queuename) && !strcasecmp(q->name, queuename)) {
so, if queue is specified and matching, there is no need to iterate
further, but found can be 0.
Regards,
Atis
> }
>
> return found ? RESULT_SUCCESS : RESULT_FAILURE;
>
--
Atis Lezdins,
VoIP Project Manager / Developer,
atis at iq-labs.net
Skype: atis.lezdins
Cell Phone: +371 28806004
Cell Phone: +1 800 7300689
Work phone: +1 800 7502835
More information about the asterisk-dev
mailing list