Closed k4ml closed 7 years ago
Hey again @k4ml :)
So I'd actually suggest using both.
Take a look at the flask-like routing docs. The examples there show that you can make a Router
, use it to define your extensions using decorated functions, and then load the router like you would any other app using a Service
instance:
from switchy import Service
from switchy.apps.routers import Router
router = Router(guards={
'Call-Direction': 'inbound',
'variable_sofia_profile': 'external'})
@router.route('00(.*)|011(.*)', response='407')
def reject_international(sess, match, router, response):
sess.respond(response)
sess.hangup()
@router.route("^(9054941990)$")
def test_did(sess, match, router):
# call our route function from above
return bridge2dest(sess, match, router, profile='external')
s = Service(['FS_host1.com', 'FS_host2.com', 'FS_host3.com'])
s.apps.load_app(router, app_id='default')
s.run() # blocks forever
To get some better insight you might want to take a look at how the Router
app is implemented.
In terms of integration with switchy serve
(from #63) I wonder if it makes sense to be able to pass a --module app_module.py
option (or similar) which tells switchy
to load the app_module.py
module and then make any defined apps available for the service to load?
What do you think?
If you have any questions please let me know :) All of the cluster service api stuff is very new so we'd appreciate any feedback you have. Also feel welcome to contribute any new ideas you come up with :+1:
Aah, right. I missed this. You can decorate multiple functions with router
instance, and pass it to Service. Now it make sense.
On loading app
, does it mean currently we can only load the app from switchy ? If yes then I think using full import path will open possibility of using any custom app, as long as they're on the import path. I think that more pythonic and inline with approach in other project like django. Just passing the class name seem a bit magic to me.
@k4ml ok sounds good I'll add support for the full module path and change the docs. Thanks for the feedback!
Are you having any luck accomplishing your goal with the new Service
stuff?
I'm interested to know :)
PS: also make sure to mention me with @tgoodlet
because I almost missed this reply ;)
@tgoodlet I have problem with ring_ready yesterday as I wrote in #65. While working on that I noticed that you're using uuid_broadcast (through sess.broadcast()
) for executing command. Before discovering that, I try to execute ring_ready through sess.con.execute('ring_ready', '', sess.uuid)
. Looking at switchy log, I didn't see the command get executed.
Any reason why uuid_broadcast is preferred over con.execute()
or con.send()` ?
@k4ml I answered in #65 btw.
Yes so broadcast()
is guaranteed to be async so you can use it on apps that normally block.
Also FreeSWITCH will internally queue up the app requests made with broadcast()
so you can guarantee ordering.
We don't use con.execute()
because it only let's you call dialplan apps and not mod_commands
commands. Also I'm pretty sure it's not async unless the underlying app is.
con.execute()
should still work but switchy
won't log anything since we haven't re-wrapped that method like we have for api()
. Feel free to make a PR for that if you want.
con.send()
doesn't return back a response like con.api()
does.
switchy
is an async cluster controller and so far con.api()
and con.bgapi()
generally have worked well for that use case.
From what I read in the docs and also initial announcement on FS mailing list, I guess switchy original use case was for load testing. In my case however, we need to handle incoming/outgoing call services. Currently we use the esl library to handle making and receiving calls. But switchy seem to also has all the call handling code that we need, and seem using better approach than what we currently has.
So just to handle incoming/outgoing calls, what do you suggest the proper way forward ? Implement our logic from the Service class:-
Or implement it as Router ? Or load it as
app
fromswitch serve
command ?