#23 ✓resolved

Problem with broken pipe in AGI when caller cancels the call

Reported by dilshodm | March 8th, 2008 @ 08:12 AM


There is a strange bug which causes Errno::EPIPE: Broken pipe error.

In Dial command when caller cancels the call, the next AGI command will return nothing and the second AGI command will break with above error.

Here is the example dialplan.rb:

dial "SIP/test"

dialstat = last_dial_status # here maybe any AGI command

dialstat = last_dial_status # as well here

Callee answers and it's OK:

DEBUG agi: >>> EXEC Dial SIP/test|60|

DEBUG agi: <<< 200 result=-1


DEBUG agi: <<< 200 result=1 (ANSWER)


DEBUG agi: <<< 200 result=1 (ANSWER)

Next situation - caller cancels the call, there is ERROR:

DEBUG agi: >>> EXEC Dial SIP/test|60|

DEBUG agi: <<< 200 result=-1


DEBUG agi: <<<


ERROR agi: #Errno::EPIPE: Broken pipe

ERROR agi: /usr/lib/ruby/gems/1.8/gems/adhearsion-0.7.999/lib/adhearsion/voip/asterisk/commands.rb:26:in `write'

/usr/lib/ruby/gems/1.8/gems/adhearsion-0.7.999/lib/adhearsion/voip/asterisk/commands.rb:26:in `print'

/usr/lib/ruby/gems/1.8/gems/adhearsion-0.7.999/lib/adhearsion/voip/asterisk/commands.rb:26:in `write'

So, as you can see, GET VARIABLE DIALSTATUS in the first doesn't return anything, in the second breaks with error.

Actually, this was the root of causing the bugs:




Comments and changes to this ticket

  • dilshodm

    dilshodm March 9th, 2008 @ 01:56 PM


    I think the problem is solved.

    I found out that this error never more happens when I use DeadAGI instead of AGI.

    Previous extensions.conf, where it was error:


    exten =>_X.,1,AGI(agi://

    The new extensions.conf, where there is no more such error:


    exten =>_X.,1,Answer

    exten =>_X.,n,DeadAGI(agi://

    exten =>_X.,n,Hangup

  • Jay Phillips

    Jay Phillips March 9th, 2008 @ 02:17 PM

    • State changed from “new” to “open”

    When the channel for which an AGI request was made hangs up, the socket closes and it's up to the AGI process to "clean up" as best it can. The clean up process shouldn't simply stop the thread dead (e.g. kill() or other_thread.raise) because there may be resources that need to be freed, etc. This is where timeout.rb in the Ruby standard library fails -- it aggressively tries to screw with other threads.

    Instead, it's a safe assumption I think to only raise the exception when trying to read/write to the socket. This happens with the "Broken pipe error".

    This is a known issue and is actually one of the ways Adhearsion's threads safely degrade. I know it's a little noisy with the backtrace but exceptions are safe as long as they're accounted for. Honestly, I've never had this become an issue personally (especially with smart use of begin/ensure closures).

    Maybe Adhearsion's AGI server could catch this and report something a little more friendly, though there are other exceptions that get raised when the socket is down such as "no method blah on NilClass"...

  • dilshodm

    dilshodm March 10th, 2008 @ 07:57 AM

    Actually, the problem is not the exception itself. It was arised when I need to retrieve some information from Asterisk by AGI, however the connection was closed.

    This is natural.

    The solution to this - is to use DeadAGI instead of AGI.

    Then after hangup we still can retrieve it's dialstatus, etc. and make database updates.

  • Jay Phillips

    Jay Phillips December 7th, 2008 @ 09:40 PM

    • Tag set to dialplan
    • State changed from “open” to “resolved”

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

Shared Ticket Bins

People watching this ticket