<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body>
<div dir="ltr">
<div>
<meta content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none">
<!--
p
        {margin-top:0;
        margin-bottom:0}
-->
</style></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Hi Alex, all</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)" dir="ltr">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
This was a super useful hint, many thanks.</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)" dir="ltr">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
For the archive's benefit, I had to tweak the failure_route a little bit. Essentially in my use case, the downstream carrier gateway is also using dispatcher, and returns me a 503 when it has no routes left. So I catch that error, then mark it as inactive,
 before trying to get the next route (without marking it inactive, I got looping). </div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)" dir="ltr">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
modparam("dispatcher", "setid_pvname", "$var(setid)")   #To tell cgrates what the dispatch destination is
<div>modparam("dispatcher","flags", 2)</div>
modparam("dispatcher", "xavp_dst", "_dsdst_")<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)" dir="ltr">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
failure_route[DISPATCH_FAILURE] {
<div><br>
</div>
<div>        if (t_is_canceled()) {</div>
<div>                xlog("CGRDISPATCHFAIL: is cancelled");</div>
<div>                exit;</div>
<div>        }</div>
<div><br>
</div>
<div>        if (t_check_status("503")  or (t_branch_timeout() and !t_branch_replied())) {</div>
<div><br>
</div>
<div>                ds_mark_dst("dp"); # set to inactive and probing</div>
<div><br>
</div>
<div>                if(!ds_next_dst()) {</div>
<div>                        xlog(Cannot set next destination in DISPATCH_FAILURE. Out of routes\n");</div>
<div>                        send_reply("503", "No destination - run out of routes");</div>
<div>                        exit;</div>
<div>                } else {</div>
<div>                        xlog("CDR Set the next domain ok grp <$var(setid)> \n");</div>
<div>                }</div>
<div><br>
</div>
<div>                t_on_failure("DISPATCH_FAILURE");</div>
<div><br>
</div>
<div><br>
</div>
<div>                route(RELAY);</div>
<div><br>
</div>
<div>        } else {</div>
<div>                send_reply("503", "DISPATCH FAILURE for non 503 error downstream");</div>
<div>                exit;</div>
<div>        }</div>
<div><br>
</div>
}<br>
</div>
<div>
<div id="appendonsend"></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
The other thing I needed to do was to return the group id for the route that was finally used to make the call. I found that to do this, I needed to call ds_is_from_list just before I relayed the call </div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
  # try and find out which group it is
<div>        if(ds_is_from_list("-1","2","$du"))</div>
<div>        {</div>
<div>                xlog("CGROUTERELAY Found grp $var(setid) for $du\n");</div>
<div>        }</div>
<div>        else</div>
<div>        {</div>
<div>                xlog("CGROUTERELAY Tried to find group for $du but failed.\n");</div>
<div>        }</div>
<div><br>
</div>
        xlog("CGRROUTERELAY: Sending call to ruri: $ru - du: <$du> grp: $var(setid)\n");<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Cheers</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)" dir="ltr">
Peter</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)" dir="ltr">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> sr-users <sr-users-bounces@lists.kamailio.org> on behalf of Alex Balashov <abalashov@evaristesys.com><br>
<b>Sent:</b> 04 September 2020 23:23<br>
<b>To:</b> sr-users@lists.kamailio.org <sr-users@lists.kamailio.org><br>
<b>Subject:</b> Re: [SR-Users] Dispatcher / ds_select_routes</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText">Hi Peter,<br>
<br>
I've never used ds_select_routes(), but--taking a stab in the dark--it <br>
seems to me the principle would be something like:<br>
<br>
-----<br>
    modparam("dispatcher", "flags", 2)<br>
<br>
    route[...] {<br>
       ...<br>
<br>
       if(!ds_select_routes("...", "d", "0")) {<br>
          sl_send_reply("503", "No initial routes");<br>
          exit;<br>
       }<br>
<br>
       t_on_failure("REROUTE");<br>
<br>
       if(!t_relay())<br>
          sl_reply_error();<br>
     }<br>
<br>
     failure_route[REROUTE] {<br>
        if(t_is_canceled())<br>
           exit;<br>
<br>
        if(!ds_next_dst()) {<br>
           send_reply("503", "Out of routes");<br>
           exit;<br>
        }<br>
<br>
        t_on_failure("REROUTE");<br>
        t_relay();<br>
     }<br>
-----<br>
<br>
A few important subtleties for which the documentation is indeed a bit <br>
sparse:<br>
<br>
- "Failover" of any kind is made possible by storing a list of <br>
destinations, in ascending order of preference based on the dispatcher <br>
algorithm chosen (and the way all the groups are concatenated, in the <br>
particular case of ds_select_routes()), in a transaction-persistent data <br>
structure called an XAVP. But this behaviour is not enabled by default, <br>
and is enabled by setting bit 2 in the "flags" modparam to dispatcher, <br>
as in the example above.<br>
<br>
- Because the chosen destination is being pushed into the destination <br>
URI (Kamailio-idiosyncratic next-hop URI) rather than the domain part of <br>
the Request URI (mode "d" for ds_select_routes()), you must use <br>
ds_next_dst() to iterate to the next step in the result set. <br>
ds_next_domain() would be appropriate only if the next destination to <br>
attempt were being stored in the "ruri", as is the case in the docs <br>
example but not in the code you posted. So, use ds_next_dst() in your <br>
failure_route instead.<br>
<br>
-- Alex<br>
<br>
On 9/4/20 5:53 PM, Peter Gradwell wrote:<br>
> Hello<br>
> <br>
> I'm doing a project where I need to route using dispatcher across <br>
> multiple groups. i.e. when the customer makes a call, the "core" server <br>
> makes a request to cgrates to get back a list of carriers that support <br>
> that, and then want to work through them in order of preference.<br>
> <br>
> e.g. the string we get back from cgrates via evapi might be "2,1,3". <br>
> i.e. try all Group 2 destinations, then group 1, then group 3.<br>
> <br>
> Each of these is then a dispatcher group (with multiple dispatcher <br>
> routes in each group).<br>
> <br>
> When the call then gets to the "Group 2" server that in turn is also <br>
> using dispatcher to handle multiple destinations, and if all of those <br>
> destinations fail, it returns a 503 to the "core", which is then meant <br>
> to try "Group 1", and so on.<br>
> <br>
> The documentation on this is a bit sparse, but what I think I am meant <br>
> to do (at the core level) is use ds_select_routes to load up the list of <br>
> groups <br>
> (<a href="https://kamailio.org/docs/modules/5.3.x/modules/dispatcher.html#dispatcher.f.ds_select_routes">https://kamailio.org/docs/modules/5.3.x/modules/dispatcher.html#dispatcher.f.ds_select_routes</a>)
<br>
> <br>
> <br>
> if(ds_select_routes("2=4;1=4;3=4", "d", "0"))<br>
> {<br>
>      t_on_failure("REROUTE");<br>
>      t_relay();<br>
>      exit;<br>
> }<br>
> <br>
> and then in my failure_route, if the error code is 503 I call <br>
> ds_next_domain, e.g.<br>
> <br>
> failure_route[REROUTE] {<br>
>      if(t_check_status("503")) {<br>
>          if(ds_next_domain()) {<br>
>              t_on_failure("REROUTE");<br>
>              t_relay();<br>
>              exit;<br>
>          }<br>
>      }<br>
> }<br>
> <br>
> My problem is, that in applying theory to practice, I have ended up with <br>
> a bunch of looping and it's not working right!<br>
> <br>
> Does anyone have an example code for such a scenario?<br>
> <br>
> many thanks<br>
> peter<br>
> <br>
> _______________________________________________<br>
> Kamailio (SER) - Users Mailing List<br>
> sr-users@lists.kamailio.org<br>
> <a href="https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users">https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users</a><br>
> <br>
<br>
-- <br>
Alex Balashov | Principal | Evariste Systems LLC<br>
<br>
Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free)<br>
Web: <a href="http://www.evaristesys.com/">http://www.evaristesys.com/</a>, <a href="http://www.csrpswitch.com/">
http://www.csrpswitch.com/</a><br>
<br>
_______________________________________________<br>
Kamailio (SER) - Users Mailing List<br>
sr-users@lists.kamailio.org<br>
<a href="https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users">https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users</a><br>
</div>
</span></font></div>
</div>
</div>
</body>
</html>