Python-ESL: ESLconnection.execute() blocked when handling channel_park under thread
I have this python code:- import time import json import logging import threading from freeswitchESL import ESL class EventThread(threading.Thread): def __init__(self, target, args): super(EventThread, self).__init__() self.target = target self.args = args def run(self): print("Running target") self.target(*self.args) def on_channel_park(e): uuid = e.getHeader('Unique-ID') print("Ringing") conn.execute('ring_ready ', '', uuid) conn.execute('sleep', '5500', uuid) conn.execute('answer', '', uuid) print("answered, playing media ...") media_url = 'http://www.noiseaddicts.com/samples_1w72b820/17.mp3' resp = conn.execute("playback", media_url, uuid) print(resp.getHeader("Reply-Text")) print("playback done") print(resp) if __name__ == '__main__': conn = ESL.ESLconnection('127.0.0.1', '8021', 'mypass') conn.events('plain', 'all') while True: e = conn.recvEvent() uuid = e.getHeader('Unique-ID') events_message = json.loads(e.serialize('json')) event_name = events_message['Event-Name'].lower() method_name = 'on_%s' % event_name print(method_name) if event_name == 'channel_park': print("spawning thread") t = EventThread(on_channel_park, args=(e,)) t.start() if event_name == 'playback_stop': conn.execute("hangup", "", uuid) print("Hanging up") Above, the code will stuck at conn.execute('ring_ready ', '', uuid) in on_channel_park(). It never went pass through until I hangup the call. In freeswitch log, it stopped at executing park(). But if I moved ring_ready, sleep, answer outside of the thread it will work, i.e I can hear a playback:- def on_channel_park(e): uuid = e.getHeader('Unique-ID') print("answered, playing media ...") media_url = 'http://www.noiseaddicts.com/samples_1w72b820/17.mp3' resp = conn.execute("playback", media_url, uuid) print(resp.getHeader("Reply-Text")) print("playback done") print(resp) if __name__ == '__main__': conn = ESL.ESLconnection('127.0.0.1', '8021', 'mypass') conn.events('plain', 'all') while True: e = conn.recvEvent() uuid = e.getHeader('Unique-ID') events_message = json.loads(e.serialize('json')) event_name = events_message['Event-Name'].lower() method_name = 'on_%s' % event_name print(method_name) if event_name == 'channel_park': print("Ringing") conn.execute('ring_ready ', '', uuid) conn.execute('sleep', '5500', uuid) conn.execute('answer', '', uuid) print("spawning thread") t = EventThread(on_channel_park, args=(e,)) t.start() Any idea why this happen ?
Late to answer. Seems no one did, so I'd say don't write event listeners that run in a Python interpreter that FreeSWITCH knows nothing about and uses threading. I looked at doing something similar in Python in the 1.2 days and after a couple of roadblocks like this, I took the advice of the wiki and the developers and developed what I needed in Lua. It worked out very well. Python gets some love in Confluence, so I assume people use it, though. I know for a fact that you can start a Lua event listener by executing a luarun command via Python ESL API. Maybe it would also work in this case to run a Python script in the interpreter managed by mod_python. Let FS manage thread state. On Tue, Apr 11, 2017 at 1:03 AM, Mohd Kamal Bin Mustafa < kamal.mustafa@gmail.com> wrote:
I have this python code:-
import time import json import logging import threading
from freeswitchESL import ESL
class EventThread(threading.Thread): def __init__(self, target, args): super(EventThread, self).__init__() self.target = target self.args = args
def run(self): print("Running target") self.target(*self.args)
def on_channel_park(e): uuid = e.getHeader('Unique-ID') print("Ringing") conn.execute('ring_ready ', '', uuid) conn.execute('sleep', '5500', uuid) conn.execute('answer', '', uuid) print("answered, playing media ...") media_url = 'http://www.noiseaddicts.com/samples_1w72b820/17.mp3' resp = conn.execute("playback", media_url, uuid) print(resp.getHeader("Reply-Text")) print("playback done") print(resp)
if __name__ == '__main__': conn = ESL.ESLconnection('127.0.0.1', '8021', 'mypass') conn.events('plain', 'all') while True: e = conn.recvEvent() uuid = e.getHeader('Unique-ID') events_message = json.loads(e.serialize('json')) event_name = events_message['Event-Name'].lower() method_name = 'on_%s' % event_name print(method_name)
if event_name == 'channel_park': print("spawning thread") t = EventThread(on_channel_park, args=(e,)) t.start()
if event_name == 'playback_stop': conn.execute("hangup", "", uuid) print("Hanging up")
Above, the code will stuck at conn.execute('ring_ready ', '', uuid) in on_channel_park(). It never went pass through until I hangup the call. In freeswitch log, it stopped at executing park().
But if I moved ring_ready, sleep, answer outside of the thread it will work, i.e I can hear a playback:-
def on_channel_park(e): uuid = e.getHeader('Unique-ID') print("answered, playing media ...") media_url = 'http://www.noiseaddicts.com/samples_1w72b820/17.mp3' resp = conn.execute("playback", media_url, uuid) print(resp.getHeader("Reply-Text")) print("playback done") print(resp)
if __name__ == '__main__': conn = ESL.ESLconnection('127.0.0.1', '8021', 'mypass') conn.events('plain', 'all') while True: e = conn.recvEvent() uuid = e.getHeader('Unique-ID') events_message = json.loads(e.serialize('json')) event_name = events_message['Event-Name'].lower() method_name = 'on_%s' % event_name print(method_name)
if event_name == 'channel_park': print("Ringing") conn.execute('ring_ready ', '', uuid) conn.execute('sleep', '5500', uuid) conn.execute('answer', '', uuid) print("spawning thread") t = EventThread(on_channel_park, args=(e,)) t.start()
Any idea why this happen ?
_________________________________________________________________________ Professional FreeSWITCH Consulting Services: consulting@freeswitch.org http://www.freeswitchsolutions.com
Official FreeSWITCH Sites http://www.freeswitch.org http://confluence.freeswitch.org http://www.cluecon.com
FreeSWITCH-users mailing list FreeSWITCH-users@lists.freeswitch.org http://lists.freeswitch.org/mailman/listinfo/freeswitch-users UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users http://www.freeswitch.org
On 10 May 2017 at 02:39, Lesley Pervis <lesley.pervis@gmail.com> wrote:
Late to answer. Seems no one did, so I'd say don't write event listeners that run in a Python interpreter that FreeSWITCH knows nothing about and uses threading.
Hi, thanks for the reply and advice. I'd appreciate that. It's been quite sometimes after I'm working on this (forgot about this email already) but with recent problem I have, I think we have to open new connection in the handler thread if we want to send another command over the esl socket. We can't reuse the same connection in the main thread. Since we're at this, what you think about doing billing in python ? It sound crazy but after seeing cgrates also doing the billing over the event socket, I think maybe it feasible - https://github.com/cgrates/cgrates/blob/master/docs/freeswitch.rst#811-sessi... I've started a PoC of billing in python and it seem to work, although I haven't put it under load and concurrent tests yet.
participants (3)
-
Kamal Mustafa
-
Lesley Pervis
-
Mohd Kamal Bin Mustafa