On 9/7/07, <b class="gmail_sendername">Atis</b> &lt;<a href="mailto:atis@best.eu.org">atis@best.eu.org</a>&gt; wrote:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
&gt; It doesn&#39;t work if you&#39;re using AddQueueMember with SIP channels, because<br>&gt; the Dial() is implicit, so you have no control over what happens after that<br>&gt; implicit Dial() finishes.<br><br>Nop, it works for Dial to SIP channels, if you set &quot;g&quot; option in Dial.
</blockquote><div><br>I call AddQueueMember like this:<br><br>AddQueueMember(queuename,SIP/1234)<br><br>When I then call<br><br>Queue(queuename)<br><br>from my dialplan, the Dial() of SIP/1234 is implicit.&nbsp; There is no priority and extension that I control where Dial() is being executed, and thus there is no &quot;priority + 1&quot; for me to go to by using the &#39;g&#39; option to Dial.
<br><br>What you&#39;re talking about only works if I do this instead:<br><br>AddQueueMember(queuename,Local/1234@agents)<br><br>And then somewhere in my dialplan I have:<br><br>[agents]<br>exten =&gt; 1234,1,Dial(SIP/1234,20)
<br>exten =&gt; 1234,n,DoSomethingHereIfDollarDialStatusIsNotANSWERED<br><br>And then of course it makes no difference that agent 1234 is on SIP - they could be Zap, IAX, Skinny, whatever.<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
&gt; And yes, I have good reason for using SIP channels.&nbsp;&nbsp;We have externally<br>&gt; driven automatic pausing (because the built-in wrapuptime is per-queue and<br>&gt; therefore broken for any agent who is assigned to more than one queue), and
<br>&gt; neither form of Local (with or without /n) perform properly under this<br>&gt; configuration.<br><br>This is something new for me. Are you sure about this? Isn&#39;t<br>wrapuptime taking in account agent state change? Because then, it&#39;s
<br>really bad for direct calls (for me it&#39;s rare that agent have several<br>queues).</blockquote><div><br>Wrapuptime isn&#39;t a state in app_queue.&nbsp; You&#39;d think it was (agent goes from &quot;in-use&quot; to &quot;in-wrapup&quot;, then back to &quot;available&quot; after the configured number of seconds).&nbsp; 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).&nbsp; You can test this easily by adding a member to two queues, then sending a call to each queue spaced a minute apart.&nbsp; Then run &#39;queue show&#39; on the CLI.&nbsp; You&#39;ll see that the &quot;last was xxx seconds ago&quot; differs for the same member in&nbsp; the two queues.
<br><br>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.
<br><br>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.
<br><br>So, the built in wrapup has three major problems compared to the ACD system we moved to Asterisk from:<br><br>- wrapuptime is per-queue-per-member, not per-member<br>- wrapuptime is invisible (the internal state of the member during the wrapup is &quot;not in use&quot;, and only by looking at the &quot;last was xxx seconds ago&quot; and knowing what the configured wrapuptime for the queue is can you tell that a member is not actually eligible to take a call)
<br>- 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)<br>
<br>These problems led to me developing this external wrapuptime system.</div></div><br>My original implementation for doing external auto-pause was to have an AMI client watch for Hangup events.&nbsp; When I did that, Local channels caused problems.&nbsp; 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.&nbsp; The other way, the hangup didn&#39;t fire until the agent was done with the caller, but some equally unpleasant side effect manifested.&nbsp; This was all months ago, so I don&#39;t recall the specific problems I faced.
<br><br>The AMI solution was too CPU intensive, so I switched to a system that essentially tails queue_log.&nbsp; 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.&nbsp; &nbsp; 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.<br><br>This way of doing things might not be incompatible with Local channels, but I&#39;d have to do some tests.<br clear="all"><br>-- <br>j.