From: Jeff L. <je...@je...> - 2016-03-24 17:44:42
|
On 03/23/2016 10:59 AM, Ralf Schlatterbeck wrote: > On Tue, Mar 22, 2016 at 12:54:44PM -0500, Jeff LaCoursiere wrote: >> In testing I first noticed that about 30% of the time the script hangs, >> thus I implemented the signal timeout. It seems to hang because I never >> get the PeerlistComplete event. Is this a problem with asterisk not >> sending it or some kind of bug in pyst? >> >> I next noticed that I rarely get the same number of peers: >> >> -------- >> >> root@jlpenha:/usr/local/bin# ./pypeers | wc -l >> 27 >> root@jlpenha:/usr/local/bin# ./pypeers | wc -l >> 68 >> root@jlpenha:/usr/local/bin# ./pypeers | wc -l >> 71 >> root@jlpenha:/usr/local/bin# ./pypeers | wc -l >> 67 >> root@jlpenha:/usr/local/bin# ./pypeers | wc -l >> 64 > You can debug this by looking with wireshark (or tcpdump) to the traffic > on port 5038. This should show you in what sequence you receive which > messages from asterisk. > > Looking at your code: You should *not* call ami.message_loop explicitly > in your code. This is done behind the scenes by the ami implementation > of pyst. So you're probably creating a race condition there between your > call to ami.message_loop and the one that is called by a thread created > in the __init__ method of the Manager object. > > So you really should leave all the processing to the thread created by > Manager and do something else (sleep?) in the main program. > > Ralf Hi, yes indeed that was the main issue. I guess two threads were fighting for the responses. Getting rid of that call and just looping forever around a sleep makes it always get all of the peers. However now I can't seem to get the main loop to exit - the timeout alarm does it eventually (after five seconds), but the same code in the handler doesn't. You can see that "printResult()" runs (the empty array shows in stdout), but the sys.exit(0) doesn't exit the parent thread I guess? I get the impression that this library is really designed around making a multi-threaded daemon that just lives to process AMI events. What I am looking for hardly requires that - a single threaded utility that just grabs some info and exits seems to be difficult to code :) Can anyone supply an example that does something similar? Here is what I have now: #!/usr/bin/python from asterisk import manager import signal import time import sys ip = "127.0.0.1" user = "XXX" passwd = "XXX" peers = [] def handleEvent(event, ami): print ("Received event: %s" % event.name) if event.name == 'PeerlistComplete': printResults() ami.close() sys.exit(0) #print ("Received event Header: %s" % event.headers) def eventTimeout(signum, frame): print "Timeout!" ami.close() sys.exit(1) def printResults(): print peers ami = manager.Manager() ami.connect(ip) ami.login(user, passwd) ami.register_event('PeerEntry', handleEvent) ami.register_event('PeerlistComplete', handleEvent) signal.signal(signal.SIGALRM, eventTimeout) # Sippeers tends to hang? signal.alarm(5) response = ami.send_action({'Action' : 'Sippeers'}) #ami.message_loop() while(1): time.sleep(10) ----- and the result: root@jlpenha:/usr/local/bin# ./pypeers Received event: PeerEntry Received event: PeerEntry Received event: PeerEntry [snip] Received event: PeerEntry Received event: PeerlistComplete [] Timeout! The "Timeout!" doesn't appear for five seconds... Cheers, j |