मैं एक अविश्वसनीय सर्वर के लिए अनुरोध को लागू करने का प्रयास कर रहा हूं। अनुरोध करना अच्छा है, लेकिन सफलतापूर्वक पूरा करने के लिए मेरी perl स्क्रिप्ट के लिए 100% आवश्यक नहीं है। समस्या यह है कि सर्वर कभी-कभी डेडलॉक करेगा (हम क्यों पता लगाने की कोशिश कर रहे हैं) और अनुरोध कभी सफल नहीं होगा। चूंकि सर्वर सोचता है कि यह लाइव है, इसलिए यह सॉकेट कनेक्शन खोलता रहता है इस प्रकार एलडब्लूपी :: उपयोगकर्ताएजेंट का टाइमआउट मान हमें अब तक अच्छा नहीं करता है। अनुरोध पर पूर्ण टाइमआउट लागू करने का सबसे अच्छा तरीका क्या है?एलडब्लूपी पर सही समय समाप्ति :: UserAgent अनुरोध विधि
एफवाईआई, यह एक DNS समस्या नहीं है। डेडलॉक में एक ही समय में हमारे पोस्टग्रेज़ डेटाबेस को मारने वाले भारी संख्या में अद्यतनों के साथ कुछ करना है। परीक्षण उद्देश्यों के लिए, हमने अनिवार्य रूप से सर्वर प्रतिक्रिया हैंडलर में थोड़ी देर (1) {} पंक्ति डाली है।
वर्तमान में, कोड तो दिखाई देता है:
my $ua = LWP::UserAgent->new;
ua->timeout(5); $ua->cookie_jar({});
my $req = HTTP::Request->new(POST => "http://$host:$port/auth/login");
$req->content_type('application/x-www-form-urlencoded');
$req->content("login[user]=$username&login[password]=$password");
# This line never returns
$res = $ua->request($req);
मैं संकेतों का उपयोग एक टाइमआउट को गति प्रदान करने की कोशिश की है, लेकिन यह काम करने के लिए प्रतीत नहीं होता।
eval {
local $SIG{ALRM} = sub { die "alarm\n" };
alarm(1);
$res = $ua->request($req);
alarm(0);
};
# This never runs
print "here\n";
अंतिम उत्तर जिसे मैं उपयोग करने जा रहा हूं, किसी को ऑफलाइन द्वारा प्रस्तावित किया गया था, लेकिन मैं इसका उल्लेख यहां करूँगा। किसी कारण से, SigAction काम करता है जबकि $ SIG (ALRM) नहीं करता है। अभी भी यकीन नहीं है क्यों, लेकिन यह काम करने के लिए परीक्षण किया गया है। यहां दो कार्य संस्करण हैं:
# Takes a LWP::UserAgent, and a HTTP::Request, returns a HTTP::Request
sub ua_request_with_timeout {
my $ua = $_[0];
my $req = $_[1];
# Get whatever timeout is set for LWP and use that to
# enforce a maximum timeout per request in case of server
# deadlock. (This has happened.)
use Sys::SigAction qw(timeout_call);
our $res = undef;
if(timeout_call(5, sub {$res = $ua->request($req);})) {
return HTTP::Response->new(408); #408 is the HTTP timeout
} else {
return $res;
}
}
sub ua_request_with_timeout2 {
print "ua_request_with_timeout\n";
my $ua = $_[0];
my $req = $_[1];
# Get whatever timeout is set for LWP and use that to
# enforce a maximum timeout per request in case of server
# deadlock. (This has happened.)
my $timeout_for_client = $ua->timeout() - 2;
our $socket_has_timedout = 0;
use POSIX;
sigaction SIGALRM, new POSIX::SigAction(
sub {
$socket_has_timedout = 1;
die "alarm timeout";
}
) or die "Error setting SIGALRM handler: $!\n";
my $res = undef;
eval {
alarm ($timeout_for_client);
$res = $ua->request($req);
alarm(0);
};
if ($socket_has_timedout) {
return HTTP::Response->new(408); #408 is the HTTP timeout
} else {
return $res;
}
}
संभावित डुप्लिकेट [पर्ल में एक निश्चित समय समाप्ति लागू करने के लिए कैसे?] (Http://stackoverflow.com/questions/15899855/how-to-enforce-a -definite-timeout-in-perl) – sixtyfootersdude