<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 23, 2015 at 9:26 AM, 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><div>On 23 Feb 2015, at 16:19, 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 Wed, Feb 11, 2015 at 11:12 AM, 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><span><div>On 11 Feb 2015, at 17:50, 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 Tue, Feb 3, 2015 at 6:11 AM, Daniel-Constantin Mierla <span dir="ltr"><<a href="mailto:miconda@gmail.com" target="_blank">miconda@gmail.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">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    <br></div></blockquote><div><br></div><div>I was thinking some more about this, and I realized that I'm not really sure how I would pick a specific Asterisk server in a pool of servers.<br><br></div><div>This is probably going to demonstrate some of my ignorance when it comes to Kamailio, but I'm going to go ahead anyway :-)<br></div><div><br>Say, for example, we have n Asterisk servers, all of which can serve any need that an inbound SIP request requires. They are generic media application servers, and Kamailio just needs to pick one and send the request to it, most likely indicating the purpose in a SIP header. Then, we may receive a request from Alice to go into a conference room:<br><br><div>INVITE <a href="mailto:sip%3Aconference@my-service-provider.com" target="_blank">sip:conference@my-service-provider.com</a> SIP/2.0<br></div><div>From: Alice <<a href="mailto:alice@super-awesome-company.com" target="_blank">alice@super-awesome-company.com</a>></div>...<br><br>And we want to proxy that request to one of our media application servers, turning it into something like this:<br><br></div><div>INVITE <a href="mailto:sip%3Aconference@asterisk-node-five.mydomain.com" target="_blank">sip:conference@asterisk-node-five.mydomain.com</a> SIP/2.0<br></div><div>From: Alice <<a href="mailto:alice@super-awesome-company.com" target="_blank">alice@super-awesome-company.com</a>></div><div>To: ...<br></div><div>X-Exec-App: Conference<br>X-Exec-App-Data: 1000<br></div></div></div></div></blockquote></span>No need to retarget unless your asterisk is really requiring that domain.</div></div></blockquote><div><br></div><div>True. The same questions exist even if we are sending the INVITE request to <a href="mailto:sip%3Aconference@asterisk-node-five.myservice-provider.com" target="_blank">sip:conference@asterisk-node-five.myservice-provider.com</a> however.<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><span><br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div>Any Asterisk server can then receive the request, extract the application to execute, and start the correct application, letting an ARI application do the heavy lifting of actually implementing the requested application.<br><br></div><div class="gmail_quote">exten => s,1,NoOp()<br></div><div class="gmail_quote"> same => n,Set(app=${PJSIP_HEADER(read,X-Exec-App)})<br></div><div class="gmail_quote"> same => n,Set(args=${PJSIP_HEADER(read,X-Exec-App-Data)})<br></div><div class="gmail_quote"><div> same => n,Stasis(${app}, ${args})<br></div><div> same => n,Hangup()<br><br></div><div>All of that is fine and good - but how did Kamailio choose "asterisk-node-five" as the Asterisk server to send the request to? </div></div></div></div></blockquote></span>There are many ways, our dispatcher module has as many ways to dispatch traffic as Asterisk has</div><div>queue algorithms.</div><div><br></div></div></blockquote><div><br></div><div>I think that's a very apt comparison :-)<br><br></div><div>The Queue application's ring strategies can be problematic. In relatively simple scenarios they apply fairly well; with sufficient complexity, you either have to use other mechanics to achieve the functionality you want (say, for example, Local channel members) or you find that your ring strategy simply isn't achievable. Sometimes, Asterisk _can_ provide you the levers to toggle the behaviour you want; however, in many complex scenarios, it can't give you all the functionality you desire. Ideally, you want the developer building a system on top of Asterisk to control the business application logic - hence, the advent of ARI. In fact, the Queue application's ring strategy limitations were a major contributing factor in the development of ARI.<br><br></div><div>The same could be said here. Sure, I can use one of the many levers that exist in the dispatcher module, and there's a reasonable chance that it will accommodate the complexity of a particular scenario. Playing around with it over the past few days, ds_select_dst is clearly very powerful. On the other hand, I'm still limited to the algorithms implemented in Kamailio. While I could write my own algorithm in C and contribute it upstream, not everyone is a C programmer!<br><br></div></div></div></div></blockquote></div></div>Which is why we have python, lua, java, perl support...</div><div><span><br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>It may be given the tight timing constraints that Kamailio exists under (which is somewhat tighter than Asterisk determining who to ring in a Call Queue) that hardcoding the algorithms in Kamailio is the best way to do it - but I'm curious if there are ways outside of that.<br></div></div></div></div></blockquote></span>Of course there are.</div><div><span><br></span></div></div></blockquote><div><br></div><div>Well, let's explore that some then. Rambling on...<br><br></div><div>Starting from the Kamailio documentation, let's say I have the following routing:<br><br><pre># main request routing logic

route {<br></pre><pre>    # <snip><br></pre><pre><br>    # dispatch destinations
    route(DISPATCH);
<br>
}
</pre><pre># Dispatch requests
route[DISPATCH] {
    # round robin dispatching on gateways group '1'
    if(!ds_select_dst("1", "4"))
    {<br>        send_reply("404", "No destination");
        exit;
    }
    xlog("L_DBG", "--- SCRIPT: going to <$ru> via <$du>\n");
    t_on_failure("RTF_DISPATCH");
    return;
}</pre>Interestingly, the example dispatcher list file hard codes the destinations in group '1', although ostensibly I suppose this could come from a database as well. Let's assume that part is solved.<br></div><div><br></div><div>Let's say I wanted to use round-robin in the example above for all requests, unless the request is for a conference. Then, I need to do the following:<br></div><div>(1) If someone from the same domain is already in a conference, I should route the request to that Asterisk server.<br></div><div>(2) If that request lands on an Asterisk server already serving conferences for that domain, I may still not be in the right location. The new request - even though it is from the same domain and wants a conference - may not want to be in the same conference as the other person. That means that it may be serviced by the Asterisk server it landed on, or, if that Asterisk server determines that it would get too loaded for handling another conference on that server, it may get bounced back to Kamailio with a "please try someone else." In that case, I want to route it to some other server.<br></div><br></div><div class="gmail_quote">While I could use htable for some of this - and having the state of that table be cached, replicated across Kamailio servers, etc. is nice - that honestly feels kind of klunky. If nothing else, I'm putting application state directly into the Kamailio routing, and that feels like it would be difficult to maintain. What happens when a new application is added (Queues, IVRs, Recording, etc.)? Yikes.<br><br></div><div class="gmail_quote">Alternatively, I could dump this out to another language, like you suggested:<br><br><pre># Dispatch requests
route[DISPATCH] {<br></pre><pre>    # ask Python what it wants to do<br></pre><pre>    python_exec("do_app_routing", "")<br></pre><pre>}</pre>Where the Python script itself does lookups. Fair enough; at that point, scaling the routing is the job of the Python developer (and can make use of some of the Kamailio primitives through the Router object - documentation looks a bit sparse on that, but okay).<br></div><div class="gmail_quote"><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><span><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><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><span><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">What's more, if those servers are truly dynamic, where we are using something like OpenStack to spin up and spin down Asterisk servers on an as-needed basis, than the mere act of knowing the pool of available Asterisk server is going to be tricky. Granted, the Asterisk servers could register themselves to Kamailio, so it will know at any one time who all is available for a resource, but it feels like the Kamailio routing could get tricky, with a lot of business logic sprinkled into it.<br></div></div></div></blockquote></span>We could add the new DMQ message buss to Asterisk which would make Kamailio aware of it.</div><div>There are many ways. Kamailio monitors the cluster with OPTIONs so if you spin up one that was </div><div>down, it won't take long before we send traffic.</div><div><span><br></span></div></div></blockquote><div><br></div><div></div><div>Or we could have Kamailio integrate with Asterisk using Corosync :-)<br><br></div><div>The DMQ message bus module looks to be rather generic. Is there any documentation on the actual messages published over the message bus?<br></div></div></div></div></blockquote></span>DMQ sip messages :-)</div><div><span><br></span></div></div></blockquote><div><br></div><div><snip><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"><br><div style="word-wrap:break-word"><div><span><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><br>The internet is certainly not overflowing with information on this topic, at the very least :-)<br><br></div><div class="gmail_extra">I agree that having the load of Asterisk feed out would be interesting. We had some discussion about this at AstriDevCon; particularly, what data items would be needed. There was some contention around exactly what should be available from Asterisk. Things that were listed were:<br><ul><li>CPU usage<br></li><li>Channel count</li><li>Memory usage</li><li>Call quality statistics (as a secondary indicator)</li><li>Distribution of response times on requests/responses</li></ul>I believe Torey mentioned that they send an INVITE request every so often and just see what happens - which is probably similar to the OPTIONS request pinging, although you'll get a bit more useful data out of the INVITE request.<br><br></div><div class="gmail_extra">Can you think of anything else?<br></div></div></blockquote></span>SUBSCRIBE/NOTIFY format for Asterisk status.</div><span></span><br clear="all"></div></blockquote></div><br></div><div class="gmail_extra">SIP would be an easy way to do it, particularly with how easily extensible the PJSIP Pub/Sub framework is.<br><br></div><div class="gmail_extra">I think this would be a good idea to flesh out more. What would the event package look like? Should Asterisk PUBLISH to Kamailio, or expect a SUBSCRIBE and produce periodic NOTIFY requests?<br></div><div class="gmail_extra"><br>-- <br><div><div dir="ltr"><div>Matthew Jordan<br></div><div>Digium, Inc. | Engineering Manager</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>