Unable to join queue (only on third call when second is ringing)

I’ve encountered a strange situation with joining a queue under a specific set of circumstances. If there is one agent in the queue talking on an active queue call and a second call begins ringing the queue, a third call that rings the queue while the second call is still ringing the queue will not be allowed to join the queue (it will be sent to the fail over destination), even when ringinuse=yes. If the agent places the first call on hold and answers the second call, the third call is able to join the queue, so this only happens when the second call is actively ringing the queue.

If the agent is not on an active call and one call begins ringing the queue, a second (and even third) call can ring the queue successfully, even if none of the calls are actually answered.

I’ve verified that the endpoint itself isn’t rejecting the third call by dialing the extension directly instead of the queue the extension is associated with. I’ve also verified that this happens with both static and dynamic agents as well as both SIP and PJSIP agents. In fact, the only way I’ve been able to get the third call to successfully join the queue under the above circumstances is by setting joinempty=yes; any other setting for joinempty results in the third call failing to join the queue.

I believe this has something to do with the way in which the queue reports the states of the agents. When looking at ‘queue show 500’, I see:

(Local/1305@from-queue/n from hint:1305@ext-local) (ringinuse enabled) (dynamic) (Not in use)

when the agent is idle.

(Local/1305@from-queue/n from hint:1305@ext-local) (ringinuse enabled) (dynamic) (in call) (In use)

when the agent is on the active first call.

(Local/1305@from-queue/n from hint:1305@ext-local) (ringinuse enabled) (dynamic) (in call) (Invalid)

when the second call begins ringing the queue, but before the second call is answered. Note that now the queue reports the agent’s state as “Invalid”. At this point, if a third call tries to join the queue I see this in the CLI:

WARNING[8445][C-00000004]: app_queue.c:8031 queue_exec: Unable to join queue '500'

I realize that this might be an edge case, but we encounter this situation daily. Has anyone else run into this situation?

This is on Asterisk v13.25.0 and Yealink T46G and T48G endpoints.

Here is my queue.conf:

[500]
announce-frequency=0
announce-holdtime=no
announce-position=no
autofill=no
autopause=no
autopausebusy=no
autopausedelay=0
autopauseunavail=no
joinempty=strict
leavewhenempty=yes
maxlen=0
memberdelay=0
min-announce-frequency=15
penaltymemberslimit=0
periodic-announce-frequency=0
queue-callswaiting=silence/1
queue-thereare=silence/1
queue-youarenext=silence/1
reportholdtime=no
retry=0
ringinuse=yes
servicelevel=60
strategy=ringall
timeout=0
timeoutpriority=app
timeoutrestart=no
weight=0
wrapuptime=0
context=

What are the values of QUEUESTATUS and ABANDONED when your caller does not enter the queue?

QUEUESTATUS is set to JOINEMPTY
ABANDONED isn’t set

There’s your problem.

There were no available agents to serve the caller to so the call fell through to the next dialplan priority.

Change your queue definition if you don’t want that behavior. look at the ‘joinempty/leaveempty’ settings.

With joinemtpy=strict, shouldn’t the call only be barred from entering the queue if there are no queue members in the queue or all of the queue members are unavailable. If that is the case, the call should still be allowed to enter the queue since there is a member in the queue and the member is available (ringinuse=yes). Moreover, the third call can join the queue if the second call isn’t actively ringing the queue. As soon as the second call is answered, the third call can enter the queue.

Let me ask this a different way… What combination of ‘joinempty/leaveempty’ settings will allow all calls to join the queue as long as there is at least one agent in the queue, irrespective of the state of the agent (i.e. on call, on hold, ringing, etc.)? The only reason a call should be barred from joining the queue is if there are no agents logged into the queue.

From the sample queues.conf

; ---------------------- Queue Empty Options ----------------------------------
;
; Asterisk has provided the "joinempty" and "leavewhenempty" options for a while
; with tenuous definitions of what they actually mean. The "joinempty" option controls
; whether a caller may join a queue depending on several factors of member availability.
; Similarly, then leavewhenempty option controls whether a caller may remain in a queue
; he has already joined. Both options take a comma-separated list of factors which
; contribute towards whether a caller may join/remain in the queue. The list of
; factors which contribute to these option is as follows:
;
; paused: a member is not considered available if he is paused
; penalty: a member is not considered available if his penalty is less than QUEUE_MAX_PENALTY
; inuse: a member is not considered available if he is currently on a call
; ringing: a member is not considered available if his phone is currently ringing
; unavailable: This applies mainly to Agent channels. If the agent is a member of the queue
;              but has not logged in, then do not consider the member to be available
; invalid: Do not consider a member to be available if he has an "invalid" device state.
;          This generally is caused by an error condition in the member's channel driver.
; unknown: Do not consider a member to be available if we are unable to determine the member's
;          current device state.
; wrapup: A member is not considered available if he is currently in his wrapuptime after
;         taking a call.
;
; For the "joinempty" option, when a caller attempts to enter a queue, the members of that
; queue are examined. If all members are deemed to be unavailable due to any of the conditions
; listed for the "joinempty" option, then the caller will be unable to enter the queue. For the
; "leavewhenempty" option, the state of the members of the queue are checked periodically during
; the caller's stay in the queue. If all of the members are unavailable due to any of the above
; conditions, then the caller will be removed from the queue.
;
; Some examples:
;
;joinempty = paused,inuse,invalid
;
; A caller will not be able to enter a queue if at least one member cannot be found
; who is not paused, on the phone, or who has an invalid device state.
;
;leavewhenempty = inuse,ringing
;
; A caller will be removed from the queue if at least one member cannot be found
; who is not on the phone, or whose phone is not ringing.
;
; For the sake of backwards-compatibility, the joinempty and leavewhenempty
; options also accept the strings "yes" "no" "strict" and "loose". The following
; serves as a translation for these values:
;
; yes - (empty) for joinempty; penalty,paused,invalid for leavewhenempty
; no - penalty,paused,invalid for joinempty; (empty) for leavewhenempty
; strict - penalty,paused,invalid,unavailable
; loose - penalty,invalid
;

I’d try invalid,unavailable,unknown

Unfortunately, any combination of those options yield the same result. I tried:

joinempty=invalid,unavailable,unknown
joinempty=invalid,unavailable
joinempty=invalid,unknown
joinempty=unavailable,unknown
joinempty=invalid
joinempty=unavailable
joinempty=unknown

If the agent is talking on the first call and a second call is ringing the agent the third call will fail while the second call is ringing the agent. If the third call comes in after the agent has answered the second call, it will be allowed into the queue.