Re: Double Click of Death on Perl Web Server
by atcroft (Abbot) on Sep 30, 2018 at 05:08 UTC
|
Based on what you are describing, my first thought is that perhaps the "double-click" you describe may result in multiple requests in a short (<=30-40 hundredths of a second) interval. This could be examined by performing and examining a packet capture while re-creating the event. If that is the case, then I would consider if a resource conflict is occurring, in which case I might consider if additional "instrumentation" can be added while investigating the problem (either to the code, or possibly even to the modules involved).
By the way, what configuration options are you providing when creating the listening socket? (Perhaps knowing this might help someone else provide a useful thought for a next step in your troubleshooting.)
Hope that helps.
| [reply] |
|
Resource conflict? What resource causes death?
| [reply] |
Re: Double Click of Death on Perl Web Server
by haj (Vicar) on Sep 30, 2018 at 08:23 UTC
|
Is there any message with the die?
Short of details, I've just another wild guess: If your browser receives a second click event while the first one isn't processed completely - maybe the client aborts the first request in a way the server doesn't expect? Inspect the error handling in case your server can't send the response (because the client closed the connection) or received an incomplete request (because the "click" caused either a lengthy POST request or some local JavaScript action which was aborted by the browser).
| [reply] |
Re: Double Click of Death on Perl Web Server
by Anonymous Monk on Sep 30, 2018 at 08:16 UTC
|
A quick idea which might be the solution, but also might be totally wrong:
By default on Linux, your process can get killed by SIGPIPE if trying to write to a socket that had been closed by the remote peer:
When writing onto a connection-oriented socket that has been shut down (by the local or the remote end) SIGPIPE is sent to the writing process and EPIPE is returned.
The signal is not sent when the write call specified the MSG_NOSIGNAL flag.
Double-clicking a link may mean that the first connection gets closed and a new connection re-established. Does it get better if you set $SIG{PIPE} = 'IGNORE';?
| [reply] [d/l] [select] |
Re: Double Click of Death on Perl Web Server
by cavac (Parson) on Oct 02, 2018 at 06:59 UTC
|
Just a side note, not really related to your problem: You might want to consider switching to IO::Socket::IP. Should be pretty much a plug in replacement, but will enable you to run dual stack (IPv4, IPv6) whenever you need it.
"For me, programming in Perl is like my cooking. The result may not always taste nice, but it's quick, painless and it get's food on the table."
| [reply] |
|
IO::Socket::INET
Reuse => 1,
Becomes:
IO::Socket::IP
ReuseAddr => 1,
ReusePort => 1,
OTOH IO::Socket::INET buys 14 years of backwards compatability:
corelist IO::Socket::INET
IO::Socket::INET was first released with perl v5.6.0 (2000-Mar-22)
corelist IO::Socket::IP
IO::Socket::IP was first released with perl v5.19.8 (2014-Jan-20)
| [reply] |
|
OTOH IO::Socket::INET buys 14 years of backwards compatability:
Don't be so sure. Just because it buys you 14 years of being in core doesn't mean that much. The current version of IO::Socket::IP has full test passes on perls as old as 5.8.1, so you are only buying something like three and a half years of extra backwards compatibility. Contrast that with how much forwards compatibility you would be buying with IO::Socket::IP in terms of transparent IPv6 support.
| [reply] |
|
OTOH IO::Socket::INET buys 14 years of backwards compatability
I'm aware of that. But frankly, any system too old to run at least Perl 5.20 with IO::Socket::IP and IPv6 (at least have support for it) is probably a major security disaster waiting to happen. For one thing, it probably still uses SSLv1 or no encryption at all.
I know there are always legitimate business reasons to run such old systems, but these days they they become overshadowed by the risk involved. Just thinking of Facebook here. Because they didn't patch a data leak when they first noticed the possibility, they might have to pay the EU a penalty of over a billion Euros. And thats just the government side, civil lawsuits may follow. That was a somewhat recent security issue, i somewhat doubt government would be more lenient if you run code that has issues for which patches are out for over a decade...
"For me, programming in Perl is like my cooking. The result may not always taste nice, but it's quick, painless and it get's food on the table."
| [reply] |
|
| [reply] |
Re: Double Click of Death on Perl Web Server
by Anonymous Monk on Sep 30, 2018 at 13:06 UTC
|
Thank you atcroft, haj and anon for the useful clues. Sorry I forgot
there is an error message, with diagnostics enabled, that's not
ambiguous and agrees with your suggestions:
Can't close(IO::Socket::INET=GLOB(0x7fbc9ab6e300)) filehandle: 'Broken pipe'
I tried a few things that didn't help (like $SIG{PIPE} = 'IGNORE') but this eval on close does the trick:
while (my $client = $server->accept) {
...
}
eval { close $client } # autodie in use
The Perl Cookbook says to use "shutdown" (0,1,2) instead of "close" but I get this:
Can't shutdown('IO::Socket::INET=GLOB(0x7fd3857a5e40)', '0'): Socket is not connected
What is the correct way to handle this condition (besides eval hack)?
Thanks again | [reply] |
|
# autodie in use
Why ?
It seems to me that death on failure is not something you want here.
Cheers, Rob
| [reply] |
|
| [reply] |
|
|
|
|
while (my $client = $server->accept) {
and the process gets a signal (say SIGCHLD), the accept will return false,
with error EINTR (interrupted system call) and your "while" loop will exit.
I've seen this bug in several other's programs and it can cause the intermittent
failure you are seeing.
Try something like
while(1) { if( my $client = $server->accept) { #accept code...
| [reply] [d/l] [select] |
|
Glad that you've solved it, but your example has another issue:
while (my $client = $server->accept) {
...
}
eval { close $client } # autodie in use
This eval doesn't do any good. Outside of the while loop the lexical variable $client isn't declared, so you are trying to close an undefined value, then throw away the error. Both use warnings; and use strict; should complain about that. I guess you want to disconnect within the loop?
| [reply] [d/l] |
|
my $server = IO::Socket::INET->new(...);
while (my $client = $server->accept) {
while (<$client>) {
...
}
...
close $client; # server dies
eval { close $client } # does not die
shutdown $client, 2; # dies
eval { shutdown $client, 2 } # does not die
}
close $server;
| [reply] |
|
Re: Double Click of Death on Perl Web Server
by Anonymous Monk on Sep 30, 2018 at 04:58 UTC
|
| [reply] |
Re: Double Click of Death on Perl Web Server
by ikegami (Patriarch) on Oct 02, 2018 at 03:05 UTC
|
| [reply] |