[asterisk-dev] app_queue, ringinuse, joinempty combination problems

Wolfgang Pichler wpichler at yosd.at
Wed Jan 21 03:32:22 CST 2009


Hi all,

i have a queue configured (realtime) with ringinuse=no and 
joinempty=strict    (running asterisk 1.4.21.1)

What i wanted to achive with this is - when there are all queue members 
already on the phone - then don't join the queue (and this should work 
with this config options if i am not wrong)

But calls will join the queue - regardless if there is a free member or not

so i have taken a look at the code - function join_queue

there you can read

        /* This is our one */
        stat = get_member_status(q, qe->max_penalty);
        if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
                *reason = QUEUE_JOINEMPTY;
        else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == 
QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_MEMBERS))
                *reason = QUEUE_JOINUNAVAIL;
        else if (q->maxlen && (q->count >= q->maxlen))
                *reason = QUEUE_FULL;
        else {

 - so when QUEUE_EMPTY_STRICT is set - and the get_member_status 
function does return QUEUE_NO_REACHABLE_MEMBERS or QUEUE_NO_MEMBERS then 
it will return with JOINUNAVAIL

if i look at the get_member_status function - i can see the following

static enum queue_member_status get_member_status(struct call_queue *q, 
int max_penalty)
{
        struct member *member;
        struct ao2_iterator mem_iter;
        enum queue_member_status result = QUEUE_NO_MEMBERS;

        ast_mutex_lock(&q->lock);
        mem_iter = ao2_iterator_init(q->members, 0);
        while ((member = ao2_iterator_next(&mem_iter))) {
                if (max_penalty && (member->penalty > max_penalty)) {
                        ao2_ref(member, -1);
                        continue;
                }

                if (member->paused) {
                        ao2_ref(member, -1);
                        continue;
                }

                switch (member->status) {
                case AST_DEVICE_INVALID:
                        /* nothing to do */
                        ao2_ref(member, -1);
                        break;
                case AST_DEVICE_UNAVAILABLE:
                        result = QUEUE_NO_REACHABLE_MEMBERS;
                        ao2_ref(member, -1);
                        break;
                default:
                        ast_mutex_unlock(&q->lock);
                        ao2_ref(member, -1);
                        return QUEUE_NORMAL;
                }
        }

        ast_mutex_unlock(&q->lock);
        return result;
}

it does handle corrent the min max penalty and the paused members. Also 
if a member is unavailable or invalid it does not count the member as 
available member - but it does ignore members which have an active call 
(and ringinuse=yes - so the member has to get considered as unavailable) !!

For me this seems to be wrong - what are you thinking about this ?

I think adding something like this in the while loop before the switch 
would make it handle it correct...

        if (!q->ringinuse && (member->status != AST_DEVICE_NOT_INUSE) && 
(member->status != AST_DEVICE_UNKNOWN)) {
                        ao2_ref(member, -1);
                        continue;
        }


regards,
Wolfgang



More information about the asterisk-dev mailing list