Fix autofill behavior in app_queue and document it's functionality in queues.conf.sample and UPGRADE.txt

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@24543 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
BJ Weschke
2006-05-03 20:01:30 +00:00
parent a21507a60a
commit 7b3f3db65d
3 changed files with 108 additions and 14 deletions

View File

@@ -73,6 +73,26 @@ Applications:
queue member channel that is taking the call. This is useful when trying
to link recording filenames back to a particular call from the queue.
* The old/current behavior of app_queue has a serial type behavior
in that the queue will make all waiting callers wait in the queue
even if there is more than one available member ready to take
calls until the head caller is connected with the member they
were trying to get to. The next waiting caller in line then
becomes the head caller, and they are then connected with the
next available member and all available members and waiting callers
waits while this happens. This cycle continues until there are
no more available members or waiting callers, whichever comes first.
The new behavior, enabled by setting autofill=yes in queues.conf
either at the [general] level to default for all queues or
to set on a per-queue level, makes sure that when the waiting
callers are connecting with available members in a parallel fashion
until there are no more available members or no more waiting callers,
whichever comes first. This is probably more along the lines of how
one would expect a queue should work and in most cases, you will want
to enable this new behavior. If you do not specify or comment out this
option, it will default to "no" to keep backward compatability with the old
behavior.
Manager:
* After executing the 'status' manager action, the "Status" manager events

View File

@@ -234,6 +234,9 @@ static int queue_persistent_members = 0;
/*! \brief queues.conf per-queue weight option */
static int use_weight = 0;
/*! \brief queues.conf [general] option */
static int autofill_default = 0;
enum queue_result {
QUEUE_UNKNOWN = 0,
QUEUE_TIMEOUT = 1,
@@ -575,6 +578,7 @@ static void init_queue(struct ast_call_queue *q)
q->roundingseconds = 0; /* Default - don't announce seconds */
q->servicelevel = 0;
q->ringinuse = 1;
q->autofill = autofill_default;
q->moh[0] = '\0';
q->announce[0] = '\0';
q->context[0] = '\0';
@@ -1860,25 +1864,75 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
}
return peer;
}
static int is_our_turn(struct queue_ent *qe)
{
struct queue_ent *ch;
struct member *cur;
int avl = 0;
int idx = 0;
int res;
/* Atomically read the parent head -- does not need a lock */
ch = qe->parent->head;
/* If we are now at the top of the head, break out */
if ((ch == qe) || (qe->parent->autofill)) {
if (option_debug)
ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
res = 1;
if (!qe->parent->autofill) {
/* Atomically read the parent head -- does not need a lock */
ch = qe->parent->head;
/* If we are now at the top of the head, break out */
if ((ch == qe) || (qe->parent->autofill)) {
if (option_debug)
ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
res = 1;
} else {
if (option_debug)
ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
res = 0;
}
} else {
/* This needs a lock. How many members are available to be served? */
ast_mutex_lock(&qe->parent->lock);
ch = qe->parent->head;
cur = qe->parent->members;
while (cur) {
if (cur->status == 1)
avl++;
cur = cur->next;
}
if (option_debug)
ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
res = 0;
ast_log(LOG_DEBUG, "There are %d available members.\n", avl);
if (qe->parent->strategy == 1) {
if (option_debug)
ast_log(LOG_DEBUG, "Even though there are %d available members, the strategy is ringall so only the head call is allowed in!\n", avl);
avl = 1;
}
while ((idx < avl) && (ch) && (ch != qe)) {
idx++;
ch = ch->next;
}
/* If the queue entry is within avl [the number of available members] calls from the top ... */
if (ch && idx < avl) {
if (option_debug)
ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
res = 1;
} else {
if (option_debug)
ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
res = 0;
}
ast_mutex_unlock(&qe->parent->lock);
}
return res;
}
@@ -3302,6 +3356,9 @@ static void reload_queues(void)
queue_persistent_members = 0;
if ((general_val = ast_variable_retrieve(cfg, "general", "persistentmembers")))
queue_persistent_members = ast_true(general_val);
autofill_default = 0;
if ((general_val = ast_variable_retrieve(cfg, "general", "autofill")))
autofill_default = ast_true(general_val);
} else { /* Define queue */
/* Look for an existing one */
AST_LIST_TRAVERSE(&queues, q, list) {

View File

@@ -8,6 +8,25 @@
; read into their recorded queues. Default is 'yes'.
;
persistentmembers = yes
;
; AutoFill Behavior
; The old/current behavior of the queue has a serial type behavior
; in that the queue will make all waiting callers wait in the queue
; even if there is more than one available member ready to take
; calls until the head caller is connected with the member they
; were trying to get to. The next waiting caller in line then
; becomes the head caller, and they are then connected with the
; next available member and all available members and waiting callers
; waits while this happens. The new behavior, enabled by setting
; autofill=yes makes sure that when the waiting callers are connecting
; with available members in a parallel fashion until there are
; no more available members or no more waiting callers. This is
; probably more along the lines of how a queue should work and
; in most cases, you will want to enable this behavior. If you
; do not specify or comment out this option, it will default to no
; to keep backward compatability with the old behavior.
;
autofill = yes
;
; Note that a timeout to fail out of a queue may be passed as part of
; an application call from extensions.conf:
@@ -73,11 +92,9 @@ persistentmembers = yes
;wrapuptime=15
;
; Autofill will follow queue strategy but push multiple calls through
; at same time. WARNING: By setting this to yes, if you have a number
; of calls waiting in queue, and only a single member becoming available
; at a time, it is more than likely NOT going to be the caller that's
; been waiting the longest that will get assigned to this newly available
; queue member.
; at same time until there are no more waiting callers or no more
; available members. The per-queue setting of autofill allows you
; to override the default setting on an individual queue level.
;
;autofill=yes
;