[asterisk-users] Cascading queues & calls not joining unavailable queues.

Atis atis at BEST.eu.org
Fri Sep 7 14:26:14 CDT 2007


On 9/7/07, James FitzGibbon <james.fitzgibbon at gmail.com> wrote:
> On 9/7/07, Atis <atis at best.eu.org> wrote:
> > > It doesn't work if you're using AddQueueMember with SIP channels,
> because
> > > the Dial() is implicit, so you have no control over what happens after
> that
> > > implicit Dial() finishes.
> >
> > Nop, it works for Dial to SIP channels, if you set "g" option in Dial.
>
> I call AddQueueMember like this:
>
> AddQueueMember(queuename,SIP/1234)
>
> When I then call
>
> Queue(queuename)
>
> from my dialplan, the Dial() of SIP/1234 is implicit.  There is no priority
> and extension that I control where Dial() is being executed, and thus there
> is no "priority + 1" for me to go to by using the 'g' option to Dial.
>
> What you're talking about only works if I do this instead:
>
> AddQueueMember(queuename,Local/1234 at agents)
>
> And then somewhere in my dialplan I have:
>
> [agents]
> exten => 1234,1,Dial(SIP/1234,20)
> exten =>
> 1234,n,DoSomethingHereIfDollarDialStatusIsNotANSWERED
>
> And then of course it makes no difference that agent 1234 is on SIP - they
> could be Zap, IAX, Skinny, whatever.
>
> > > And yes, I have good reason for using SIP channels.  We have externally
> > > driven automatic pausing (because the built-in wrapuptime is per-queue
> and
> > > therefore broken for any agent who is assigned to more than one queue),
> and
> > > neither form of Local (with or without /n) perform properly under this
> > > configuration.
> >
> > This is something new for me. Are you sure about this? Isn't
> > wrapuptime taking in account agent state change? Because then, it's
> > really bad for direct calls (for me it's rare that agent have several
> > queues).
>
> Wrapuptime isn't a state in app_queue.  You'd think it was (agent goes from
> "in-use" to "in-wrapup", then back to "available" after the configured
> number of seconds).  But what really happens is that the last time a member
> took a call is part of the member struct, which is subordinate to the queue
> struct ( i.e. the last time a member took a call is stored
> per-member-per-queue, not per-member).  You can test this easily by adding a
> member to two queues, then sending a call to each queue spaced a minute
> apart.  Then run 'queue show' on the CLI.  You'll see that the "last was xxx
> seconds ago" differs for the same member in  the two queues.
>
> When app_queue is attempting to dequeue a call to an available agent, it
> checks if the current time minus the time of the last call for the member in
> this queue is less than the wrapuptime, and if it is, it skips that member
> and goes onto the next.
>
> Because the last call time is per queue, you can have an agent take a call
> on queue foo, hang up that call, and receive a call for queue bar one second
> later, even if both queue foo and queue bar have a wrapuptime of 60 seconds
> configured.
>
> So, the built in wrapup has three major problems compared to the ACD system
> we moved to Asterisk from:
>
> - wrapuptime is per-queue-per-member, not per-member
> - wrapuptime is invisible (the internal state of the member during the
> wrapup is "not in use", and only by looking at the "last was xxx seconds
> ago" and knowing what the configured wrapuptime for the queue is can you
> tell that a member is not actually eligible to take a call)
> - wrapuptime cannot be shortened or extended by the agent (or anyone else
> for that matter - I once mused with writing a dialplan function to set the
> last call time to some arbitrary epoch value to make this viable)
>
> These problems led to me developing this external wrapuptime system.
> My original implementation for doing external auto-pause was to have an AMI
> client watch for Hangup events.  When I did that, Local channels caused
> problems.  If I used one form of Local channel (with or without the /n, I
> forget now) then the hangup event was fired when the call was bridged to the
> agent.  The other way, the hangup didn't fire until the agent was done with
> the caller, but some equally unpleasant side effect manifested.  This was
> all months ago, so I don't recall the specific problems I faced.
>
> The AMI solution was too CPU intensive, so I switched to a system that
> essentially tails queue_log.  When it seems COMPLETEAGENT or COMPLETECALLER
> or TRANSFER, it uses AMI to pause the member, and schedules an unpause for x
> seconds in the future.    By using PauseQueueMember without a queue name, it
> pauses an agent in all their queues, and if the agent needs to, he can
> unpause themselves early or cancel the pending unpause to give themselves
> more time to write notes.
>
> This way of doing things might not be incompatible with Local channels, but
> I'd have to do some tests.

Wow, hearing this is really interesting, and probably very valuable
for a lot of people. I just wrote a function to pause agent after
receiving call - business didn't wanted to have wrapuptime, as it
varies a lot for agents, and they also are writing notes after call.
So, they manually have to do unpause. I'm not sure about "cancel
pending unpause", because that way agent is distracted from taking
notes.

What i have is quite hard to describe - Queue sends calls to Agent/
channel, that has dial context bound to (the problem with Local/
channels is - that Queue can't follow their status, if call arrives
from outside queue). Plus i have a double-extension system, stored in
MySQL, so before Dial i check to what SIP/ channel should i ring - i
just don't remember how exactly, but this all together magically works
(yes, it needs quite much of refactoring after 1.4)

In your case, i would go for adding an per-agent (per channel?)
wrapuptime into asterisk. So, that queue checks it's own wrapuptime,
and then global agent wrapuptime (in case it's greater than queue's).
Actually, i would benefit from this also :)

Regards,
Atis

-- 
Atis Lezdins,
IT Responsible of BEST Riga,
atis at BEST.eu.org
ICQ: 142239285
Skype: atis.lezdins
Cell Phone: +371 28806004 [Tele2, Latvia]
Work phone: +1 800 7502835 [Toll free, USA]
?BEST? -> www.BEST.eu.org



More information about the asterisk-users mailing list