Summary: | ASTERISK-27017: app_queue: Linear queue retries as many agents as were skipped | ||
Reporter: | Jared Hull (fortytwo) | Labels: | |
Date Opened: | 2017-05-25 14:36:48 | Date Closed: | |
Priority: | Major | Regression? | |
Status: | Open/New | Components: | Applications/app_queue |
Versions: | 13.15.0 13.16.0 14.5.0 | Frequency of Occurrence | |
Related Issues: | |||
Environment: | Attachments: | ( 0) log.txt ( 1) queues.conf.txt | |
Description: | When using a linear or rrmemory queue, all agents are dialed in the order they are added to queues.conf. With the option 'n' added to the queue application, I would expect the queue to stop once it has reached the timeout of the last agent. It does this when all agents are (Not in use).
n - No retries on the timeout; will exit this application and go to the next step Paused or unavailable agents (due to an unavailable contact status) will be skipped and cause the queue to loop around to the first agent and ring as many agents as there were paused or unavailable before 'Exiting on time-out cycle'. {quote}exten => 424242,1,Answer same => n,Queue(linearQ,wxRn) same => n(noAnswer),Busy{quote} {quote}testbed*CLI> queue show linearQ has 0 calls (max unlimited) in 'linear' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 60s Members: PJSIP/109 (ringinuse enabled) (paused) (Not in use) has taken no calls yet PJSIP/100 (ringinuse enabled) (Unavailable) has taken no calls yet PJSIP/103 (ringinuse enabled) (Not in use) has taken no calls yet PJSIP/102 (ringinuse enabled) (Not in use) has taken no calls yet No Callers{quote} The test case in log.txt, the order of agents and status is show above. the expected behaviour is that 103 and 102 would ring before the caller exits the queue to the next line in dialplan. Instead we see the queue loop around and dial both 103 and 102 again. If 109 was unpaused, it rings 109,103,102 and then loops around to 109 again because 100 is unavailable. | ||
Comments: | By: Asterisk Team (asteriskteam) 2017-05-25 14:36:49.396-0500 Thanks for creating a report! The issue has entered the triage process. That means the issue will wait in this status until a Bug Marshal has an opportunity to review the issue. Once the issue has been reviewed you will receive comments regarding the next steps towards resolution. A good first step is for you to review the [Asterisk Issue Guidelines|https://wiki.asterisk.org/wiki/display/AST/Asterisk+Issue+Guidelines] if you haven't already. The guidelines detail what is expected from an Asterisk issue report. Then, if you are submitting a patch, please review the [Patch Contribution Process|https://wiki.asterisk.org/wiki/display/AST/Patch+Contribution+Process]. By: Benjamin Keith Ford (bford) 2017-06-05 11:49:22.954-0500 Thank you for posting this issue! We have confirmed that this is reproducible. By: Tom Hughes (tomhughes) 2017-08-21 06:41:38.611-0500 I believe the cause is basically down to this line in app_queue.c: {code} /* exit after 'timeout' cycle if 'n' option enabled */ if (noption && tries >= ao2_container_count(qe.parent->members)) { {code} Which exits once the number of lines tried is equal to the number of members of the queue, including any that aren't currently available. By: Jared Hull (fortytwo) 2017-08-22 11:50:19.291-0500 try_calling() increments 'tries' before setting up a call attempt, then it looks for a member to dial. It doesn't attempt the unavailable or paused members, nor does it count them towards the 'tries'. This is why it is ringing the same members until 'tries' is greater than or equal to the member count. tries=0 {quote}app_queue.c: PJSIP/108-00000005 is trying to call a queue member. app_queue.c: Trying 'PJSIP/107' with metric 0 app_queue.c: PJSIP/107 not available, can't receive call app_queue.c: Trying 'PJSIP/108' with metric 1 app_queue.c: PJSIP/108 paused, can't receive call app_queue.c: Trying 'PJSIP/109' with metric 2 app_queue.c: Add PJSIP/109 to pending_members{quote} tries=1 {quote}app_queue.c: PJSIP/108-00000005 is trying to call a queue member. app_queue.c: Trying 'PJSIP/201' with metric 3 app_queue.c: Add PJSIP/201 to pending_members{quote} tries=2 {quote}PJSIP/108-00000005 is trying to call a queue member. app_queue.c: Trying 'PJSIP/107' with metric 0 app_queue.c: PJSIP/107 not available, can't receive call app_queue.c: Trying 'PJSIP/108' with metric 1 app_queue.c: PJSIP/108 paused, can't receive call app_queue.c: Trying 'PJSIP/109' with metric 2 app_queue.c: Add PJSIP/109 to pending_members{quote} tries=3 {quote}app_queue.c: PJSIP/108-00000005 is trying to call a queue member. app_queue.c: Trying 'PJSIP/201' with metric 3 app_queue.c: Add PJSIP/201 to pending_members{quote} tries=4 {quote}Exiting on time-out cycle{quote} I suppose this is intended behavior to check the status of the members before each attempt, since they are certainly capable of changing. I think the solution here, without breaking any use cases when noption=0, would be to do this when noption=1: linear - Don't skip any ordered members. If they are unavailable or paused at the time they are supposed to be tried, they should be treated as failed attempts before trying the next ordered member. rrordered - Same as the above, except we must start and end at a certain member. rrmemory - Not sure, I think the order of these members changes? |