<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 23, 2015 at 2:07 PM, Olle E. Johansson <span dir="ltr"><<a href="mailto:oej@edvina.net" target="_blank">oej@edvina.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><br><div><div><div class="h5"><div>On 23 Feb 2015, at 20:10, Matthew Jordan <<a href="mailto:mjordan@digium.com" target="_blank">mjordan@digium.com</a>> wrote:</div><br><blockquote type="cite"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 23, 2015 at 11:16 AM, James Cloos <span dir="ltr"><<a href="mailto:cloos@jhcloos.com" target="_blank">cloos@jhcloos.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">>>>>> "MJ" == Matthew Jordan <<a href="mailto:mjordan@digium.com" target="_blank">mjordan@digium.com</a>> writes:<br>
<br>
MJ> What I'm trying to reason out is: given a set of routing constraints -<br>
MJ> which includes not only load balancing but also "application" level routing<br>
MJ> decisions - what's the appropriate place for that information to live?<br>
MJ> Particularly when you want your entire system - not just Asterisk - to be<br>
MJ> scalable?<br>
<br>
You need to use something to keep track of whether each box is reachable<br>
and what each is doing.  There a lots of ways of doing that, including<br>
custom network applications, shared networkable databases, shared nfs,<br>
et alia.<br>
<br>
Then each node needs a bit of logic to use that data to determine what<br>
to do with any given event.<br>
<br>
As one example, if a sip server gets an invite which directs on to an<br>
existing conference, it needs to know which asterisk is handling that<br>
conference, so that it can send the invite there.<br>
<br>
A shared database is required, but whether it is a custom application, a<br>
networkable db or a local db stored on a networked file systems is<br>
something anyone writing the code needs to choose.<br clear="all"></blockquote></div><br></div><div class="gmail_extra">Completely agree.<br><br></div><div class="gmail_extra">What I'm driving towards - albeit in something of a roundabout fashion - are two notions:<br></div><div class="gmail_extra">(1) Hard coding logic in application configuration does not lend itself well to scalability. Kamailio lessens the pain in certain ways - you're typically going to have fewer proxies than application servers (although, I suppose that depends on what you are doing). Also, as Olle pointed out, you can replicate information out using an htable. Or use a database. To some extent though, this is not much different than using func_odbc with Asterisk (a concept many people miss often.) At the same time, requiring direct access to a database from my routing engine/media application server does not lend itself well to expressive logic. While I've managed to push the data out of the application, I haven't necessarily done the same with the business rules.<br><br></div><div class="gmail_extra">If you approach the problem purely from a "how horizontally scalable can I make this," then ideally most of your business logic would lie outside of the routing engine (Kamailio) or the media application server (Asterisk). That may mean a web microservice architecture that exposes REST APIs for the real-time component to consume. That may mean something else. As Daniel noted, the more REST APIs you hit using a cURL module (or what
 have you), the slower things get in Kamailio. The same is true for 
Asterisk. What I'm trying to fish for is where that dividing line should occur - that is, what properly belongs to Kamailio (routing decisions) and what properly belongs to something else.<br><br></div><div class="gmail_extra">(2) Domain specific languages require domain specific knowledge. This is not necessarily a bad thing. At the same time, it's far easier to parallelize the problem of application development if you can split tasks into well defined domains that make use of tools that have a wider base of knowledge. If, for example, the logic of "who is in a conference on which server" can be answered by a REST API written in Python, or JavaScript, or something else - and does not even live on the Kamailio server - then not only does the job of the Kamailio integrator become easier, it is also becomes easier to find multiple people to help write the services that it integrates with.<br></div></div></blockquote><br></div></div>Kamailio really doesn't need to know as long as Asterisk knows... You are trying to solve something that is not really a problem, Matt. I have tried this path before with conferences and ended up with something too complex. Went back to</div><div>forking, if a server responded with 200 OK I added a temporary state in an autoexpire hashtable so I remembered for next call which did not need to fork. Simple. Fast. No distributed states.</div><div><br></div><div>The real key to scalability is keeping it simple and keeping states local. As soon as you start trying to synch or distribute states it gets very complex and you loose a lot of scalability. Asterisk is filled with all kinds of states, keep it there as much as possible and be smart with your signalling. You want to be able to restart Kamailio anytime without loosing states and without disrupting any single call. As soon as you start adding call states, server states and conference server states you loose a lot of that and end up with replication in databases and other complex schemes.</div><div><br></div></div></blockquote><div><br></div><div>Really, distributing the state in Asterisk is not much of a problem in this scenario. Sure, if the application in question is ConfBridge, or Queue, or some other dialplan application, then the difficulty of sharing that state across clustered Asterisk instances is non-trivial. However, in a system where the application state lives off of the Asterisk boxes - that is, where ARI is used to control the Asterisk instances and an external process (or set of processes - everyone must scale!) manages the application state - then the question of how the application state distributed is solved.<br><br></div><div>That is: I'm not really questioning where the application state lives. I'm questioning how routing decisions - which may be impacted by that application state - should be made. It sounds like the answer is "don't worry, and just use Kamailio's built-in routing mechansims." Which is an acceptable answer - there's ways to work with that answer in a clustered Asterisk environment.<br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div></div><div>Forking doesn't cost much, really. Using SIP makes life simple. The network flow is already established.</div><div><br></div></div></blockquote><div><br></div><div>Forking to all Asterisk servers is certainly a solution. I could also 302 the INVITE request or send a REFER request to the initiator to move the session to another Asterisk server if the one it lands on isn't the one that is "correct" based on some application state. Handling that at the application level is relatively straight forward; my line of questioning was really to make sure that there isn't some mechanism in Kamailio that would be more appropriate.<br></div><div><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div></div><div>If you are looking for restful interfaces, Kamailio has an embedded HTTP server you can use for quite a lot compared with the Asterisk one. The HTTP requests are as configurable and routable as the SIP requests... Quite cool.</div><div><br></div></div></blockquote><div><br></div><div>You do know we built all of ARI on the internal Asterisk HTTP server, right? :-)<br><br></div><div>Of course, the request callbacks aren't exposed to the dialplan - but then again, that's not really a concept that the Asterisk dialplan syntax would handle well. <br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div></div><div>There are a few applications that require more states, like trying to build a PBX in Kamailio. - but why try that when Asterisk has all the functionality you need? :-)</div><div><br></div><div>Keep the states where they belong. </div><div><br></div><div>Now for load balancing, we could add a module to Asterisk that sends simple SIP messages with an attachment that describes current call load and maybe a few global variables that I configure. application/asteriskstate - simple json structure that we can parse in Kamailio and use for load balancing on call and cpu load. This could be a subscribe/notify event package that Kamailio feeds into the DMQ cluster.</div><div><br></div></div></blockquote><div><br></div><div>Since this would be consumable in Kamailio, a spec on the event package would be handy.<br><br></div><div>I noticed that there are some RFCs for this already. Most are informational, although RFC 7200 looks to take things to quite a logical extreme. Any thoughts on these?<br><br></div><div>* RFC 5390: Requirements for Management of Overload in the Session Initiation Protocol - <a href="https://tools.ietf.org/html/rfc5390">https://tools.ietf.org/html/rfc5390</a><br></div><div>* RFC 6357: Design Considerations for Session Initiation Protocol (SIP) Overload Control - <a href="https://tools.ietf.org/html/rfc6357">https://tools.ietf.org/html/rfc6357</a><br></div><div>* RFC 7200: A Session Initiation Protocol (SIP) Load-Control Event Package - <a href="https://tools.ietf.org/html/rfc7200">https://tools.ietf.org/html/rfc7200</a><br><br><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div></div><div>Another thing would be to have events triggered on startup of asterisk and shutdown - maybe something as simple as a REGISTER. These could be used to enable and disable one  Asterisk server in a dispatcher set.</div><span class=""><font color="#888888"><div><br></div></font></span><br clear="all"></div></blockquote></div><br></div><div class="gmail_extra">I would imagine that in any clustered scenario, you would want Asterisk to REGISTER to Kamailio to notify it of its existence. If a SUBSCRIBE/NOTIFY scheme were used to inform Kamailio of the loaded status of the Asterisk instances, Kamailio could then SUBSCRIBE to Asterisk and start receiving subsequent NOTIFY requests.<br></div><div class="gmail_extra"><br>-- <br><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Matthew Jordan<br></div><div>Digium, Inc. | Director of Technology<br></div><div>445 Jan Davis Drive NW - Huntsville, AL 35806 - USA</div><div>Check us out at: <a href="http://digium.com" target="_blank">http://digium.com</a> & <a href="http://asterisk.org" target="_blank">http://asterisk.org</a></div></div></div></div></div>
</div></div>