Comparison

net/dns.lua @ 10957:8902cecbdd39

net.dns: Add jitter to spread queries and reduce failures due to congestion
author Matthew Wild <mwild1@gmail.com>
date Thu, 25 Jun 2020 15:29:49 +0100
parent 10956:03a09fa02e8e
child 10958:25680ece29c2
comparison
equal deleted inserted replaced
10956:03a09fa02e8e 10957:8902cecbdd39
70 end; 70 end;
71 }; 71 };
72 local get, set = ztact.get, ztact.set; 72 local get, set = ztact.get, ztact.set;
73 73
74 local default_timeout = 15; 74 local default_timeout = 15;
75 local default_jitter = 1;
76 local default_retry_jitter = 2;
75 77
76 -------------------------------------------------- module dns 78 -------------------------------------------------- module dns
77 local _ENV = nil; 79 local _ENV = nil;
78 -- luacheck: std none 80 -- luacheck: std none
79 local dns = {}; 81 local dns = {};
666 -- socket layer -------------------------------------------------- socket layer 668 -- socket layer -------------------------------------------------- socket layer
667 669
668 670
669 resolver.delays = { 1, 3 }; 671 resolver.delays = { 1, 3 };
670 672
673 resolver.jitter = have_timer and default_jitter or nil;
674 resolver.retry_jitter = have_timer and default_retry_jitter or nil;
671 675
672 function resolver:addnameserver(address) -- - - - - - - - - - addnameserver 676 function resolver:addnameserver(address) -- - - - - - - - - - addnameserver
673 self.server = self.server or {}; 677 self.server = self.server or {};
674 append(self.server, address); 678 append(self.server, address);
675 end 679 end
853 --print ('query id', id, qclass, qtype, qname) 857 --print ('query id', id, qclass, qtype, qname)
854 local o = { 858 local o = {
855 packet = header..question, 859 packet = header..question,
856 server = self.best_server, 860 server = self.best_server,
857 delay = 1, 861 delay = 1,
858 retry = socket.gettime() + self.delays[1] 862 retry = socket.gettime() + self.delays[1];
859 qclass = qclass; 863 qclass = qclass;
860 qtype = qtype; 864 qtype = qtype;
861 qname = qname; 865 qname = qname;
862 }; 866 };
863 867
867 871
868 local conn, err = self:getsocket(o.server) 872 local conn, err = self:getsocket(o.server)
869 if not conn then 873 if not conn then
870 return nil, err; 874 return nil, err;
871 end 875 end
872 conn:send (o.packet) 876 if self.jitter then
877 timer.add_task(math.random()*self.jitter, function ()
878 conn:send(o.packet);
879 end);
880 else
881 conn:send(o.packet);
882 end
873 883
874 -- remember which coroutine wants the answer 884 -- remember which coroutine wants the answer
875 if co then 885 if co then
876 set(self.wanted, qclass, qtype, qname, co, true); 886 set(self.wanted, qclass, qtype, qname, co, true);
877 end 887 end
918 local retried; 928 local retried;
919 if o.retries < #self.server then 929 if o.retries < #self.server then
920 sock, err = self:getsocket(o.server); 930 sock, err = self:getsocket(o.server);
921 if sock then 931 if sock then
922 retried = true; 932 retried = true;
933 if self.retry_jitter then
934 local delay = self.delays[((o.retries-1)%#self.delays)+1] + (math.random()*self.retry_jitter);
935 log("debug", "retry %d in %0.2fs", o.retries, delay);
936 timer.add_task(delay, function ()
937 sock:send(o.packet);
938 end);
939 else
923 log("debug", "retry %d (immediate)", o.retries); 940 log("debug", "retry %d (immediate)", o.retries);
924 sock:send(o.packet); 941 sock:send(o.packet);
942 end
925 end 943 end
926 end 944 end
927 if not retried then 945 if not retried then
928 log("debug", 'tried all servers, giving up'); 946 log("debug", 'tried all servers, giving up');
929 self:cancel(o.qclass, o.qtype, o.qname); 947 self:cancel(o.qclass, o.qtype, o.qname);