[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