[SR-Users] Dispatcher / ds_select_routes
Peter Gradwell
peter at gradwell.com
Wed Sep 9 19:13:20 CEST 2020
Hi Alex, all
This was a super useful hint, many thanks.
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).
modparam("dispatcher", "setid_pvname", "$var(setid)") #To tell cgrates what the dispatch destination is
modparam("dispatcher","flags", 2)
modparam("dispatcher", "xavp_dst", "_dsdst_")
failure_route[DISPATCH_FAILURE] {
if (t_is_canceled()) {
xlog("CGRDISPATCHFAIL: is cancelled");
exit;
}
if (t_check_status("503") or (t_branch_timeout() and !t_branch_replied())) {
ds_mark_dst("dp"); # set to inactive and probing
if(!ds_next_dst()) {
xlog(Cannot set next destination in DISPATCH_FAILURE. Out of routes\n");
send_reply("503", "No destination - run out of routes");
exit;
} else {
xlog("CDR Set the next domain ok grp <$var(setid)> \n");
}
t_on_failure("DISPATCH_FAILURE");
route(RELAY);
} else {
send_reply("503", "DISPATCH FAILURE for non 503 error downstream");
exit;
}
}
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
# try and find out which group it is
if(ds_is_from_list("-1","2","$du"))
{
xlog("CGROUTERELAY Found grp $var(setid) for $du\n");
}
else
{
xlog("CGROUTERELAY Tried to find group for $du but failed.\n");
}
xlog("CGRROUTERELAY: Sending call to ruri: $ru - du: <$du> grp: $var(setid)\n");
Cheers
Peter
________________________________
From: sr-users <sr-users-bounces at lists.kamailio.org> on behalf of Alex Balashov <abalashov at evaristesys.com>
Sent: 04 September 2020 23:23
To: sr-users at lists.kamailio.org <sr-users at lists.kamailio.org>
Subject: Re: [SR-Users] Dispatcher / ds_select_routes
Hi Peter,
I've never used ds_select_routes(), but--taking a stab in the dark--it
seems to me the principle would be something like:
-----
modparam("dispatcher", "flags", 2)
route[...] {
...
if(!ds_select_routes("...", "d", "0")) {
sl_send_reply("503", "No initial routes");
exit;
}
t_on_failure("REROUTE");
if(!t_relay())
sl_reply_error();
}
failure_route[REROUTE] {
if(t_is_canceled())
exit;
if(!ds_next_dst()) {
send_reply("503", "Out of routes");
exit;
}
t_on_failure("REROUTE");
t_relay();
}
-----
A few important subtleties for which the documentation is indeed a bit
sparse:
- "Failover" of any kind is made possible by storing a list of
destinations, in ascending order of preference based on the dispatcher
algorithm chosen (and the way all the groups are concatenated, in the
particular case of ds_select_routes()), in a transaction-persistent data
structure called an XAVP. But this behaviour is not enabled by default,
and is enabled by setting bit 2 in the "flags" modparam to dispatcher,
as in the example above.
- Because the chosen destination is being pushed into the destination
URI (Kamailio-idiosyncratic next-hop URI) rather than the domain part of
the Request URI (mode "d" for ds_select_routes()), you must use
ds_next_dst() to iterate to the next step in the result set.
ds_next_domain() would be appropriate only if the next destination to
attempt were being stored in the "ruri", as is the case in the docs
example but not in the code you posted. So, use ds_next_dst() in your
failure_route instead.
-- Alex
On 9/4/20 5:53 PM, Peter Gradwell wrote:
> Hello
>
> I'm doing a project where I need to route using dispatcher across
> multiple groups. i.e. when the customer makes a call, the "core" server
> makes a request to cgrates to get back a list of carriers that support
> that, and then want to work through them in order of preference.
>
> e.g. the string we get back from cgrates via evapi might be "2,1,3".
> i.e. try all Group 2 destinations, then group 1, then group 3.
>
> Each of these is then a dispatcher group (with multiple dispatcher
> routes in each group).
>
> When the call then gets to the "Group 2" server that in turn is also
> using dispatcher to handle multiple destinations, and if all of those
> destinations fail, it returns a 503 to the "core", which is then meant
> to try "Group 1", and so on.
>
> The documentation on this is a bit sparse, but what I think I am meant
> to do (at the core level) is use ds_select_routes to load up the list of
> groups
> (https://kamailio.org/docs/modules/5.3.x/modules/dispatcher.html#dispatcher.f.ds_select_routes)
>
>
> if(ds_select_routes("2=4;1=4;3=4", "d", "0"))
> {
> t_on_failure("REROUTE");
> t_relay();
> exit;
> }
>
> and then in my failure_route, if the error code is 503 I call
> ds_next_domain, e.g.
>
> failure_route[REROUTE] {
> if(t_check_status("503")) {
> if(ds_next_domain()) {
> t_on_failure("REROUTE");
> t_relay();
> exit;
> }
> }
> }
>
> My problem is, that in applying theory to practice, I have ended up with
> a bunch of looping and it's not working right!
>
> Does anyone have an example code for such a scenario?
>
> many thanks
> peter
>
> _______________________________________________
> Kamailio (SER) - Users Mailing List
> sr-users at lists.kamailio.org
> https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
>
--
Alex Balashov | Principal | Evariste Systems LLC
Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free)
Web: http://www.evaristesys.com/, http://www.csrpswitch.com/
_______________________________________________
Kamailio (SER) - Users Mailing List
sr-users at lists.kamailio.org
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kamailio.org/pipermail/sr-users/attachments/20200909/d28e1d9f/attachment.htm>
More information about the sr-users
mailing list