昨日でたNet::DNS::Lite-0.09の変更点に関する話。
Furlと組み合わせて使うと幸せになれる Net::DNS::Lite のtimeoutとretry回りは若干変わった実装になっていて、
use Net::DNS::Lite;
my $r = Net::DNS::Lite->new(
server => [qw/8.8.8.8 8.8.4.4/]
);
$r->resolve("google.com", "a");
このように実行すると、
#サーバ一覧 [server,timeout]
my @retry = (
['8.8.8.8',2],
['8.8.4.4',2],
['8.8.8.8',5],
['8.8.4.4',5],
['8.8.8.8',5],
['8.8.4.4',5]
);
2秒=>5秒=>5秒とタイムアウト時間が変化しつつ、上の順番でサーバ一覧が作られ、実行される。
これはどこで指定されているかというと、
sub new {
my ($class, %arg) = @_;
my $self = bless {
server => [],
timeout => [2, 5, 5],
search => [],
ndots => 1,
reuse => 300,
%arg,
}, $class;
このnewの中で指定されている。なぜ2秒なのか聞いてみたところ、
http://twitter.com/kazuho/status/215635164888436737
とのこと。まぁちょうどいいかなと言う気もする。
ところが、serverを指定せずに呼び出す(inet_atonを使う場合も)と事情が違う。
Net::DNS::Liteはserverが指定されていないと、/etc/resolv.conf を読みサーバ一覧を作る。
resolv.conf が
nameserver 192.168.0.1
nameserver 192.168.0.2
となっていれば当然、serverは [qw/192.168.0.1 192.168.0.2/] になる。
resolv.conf には optionでtimeoutやattempts(再試行回数)も書けて、
nameserver 192.168.0.1
option timeout:1 attempts:2
となるんだけど、Net::DNS::Liteの0.08まではattemptsがサポートされてなかったので、上記の場合、
servers => [qw/192.168.0.1/],
timeout => [1]
となり、サーバ一覧は
@retry = (
['192.168.0.1',1]
);
となって、1回しかDNSにアクセスしなくなってしまう(それはそれで良い場合もあるとは思う)
また、標準的なresolverではtimeoutとattemptsのデフォルトは 5と2なので
nameserver 192.168.0.1
option timeout:1
このresolv.confは
# new
servers => [qw/192.168.0.1/],
timeout => [1,1]
# 一覧
@retry = (
['192.168.0.1',1],
['192.168.0.1',1]
);
となって欲しいところ。
ということで、resolv.confにtimeoutもしくはattemptsがあるときだけ、timeoutを計算しなおすようにkazuhoさんにpullreqを送ってバージョンアップして頂きました。
初期のtimeoutが[2,5,5]なのが標準的な動作と違うのはどうなんだろうなぁと少し考えましたが、2秒というtimeoutが実践的っぽいし、バージョンアップで動作が変わるのもよくないと思い、変更しない方向になりました。