M
megapode
Hi all,
I have a pair of programs that I use for moving text files (mostly CSV
or XML) around a WAN. I use HTTP to handle the authentication and to
move the data, so the client side program mimics some of the behaviour
of a web browser.
I want to eventually refactor the code (too much global data) but first
I want to make it more robust so that it can handle network or server
failures better.
Note: during a single session I would typically write to and then read
from the same socket. It works well when the WAN connections are good
and the server is up and running, but it doesn't handle some error
conditions well.
In particular I have a problem when sending data and Apache on the
server shuts down. This is an unusual but possible scenario - we might
be shutting the server down for maintenance or because we want to stop
data coming in for whatever reason.
The socket is opened in a subroutine...
sub openSocket{
# first set up the socket timer
$socketTimer = IO::Select->new();
unless($socket = IO::Socket::INET->new(PeerAddr => $remoteSite,
PeerPort => 80,
Proto => "tcp",
Timeout => 10,
Type => SOCK_STREAM)
){
$errorStatus = "8192";
$returnedMessage = "Can't connect to $remoteSite";
print "$localMessage$returnedMessage\n" if ($debug);
}
# add the timer if we connected
$socketTimer->add($socket) unless $errorStatus;
}
All writing to the socket is done through a subroutine too...
sub writeToSocket{
# check socket still open
if($socketTimer->can_write(30)){
syswrite($socket, $oline);
}
else
{
$errorStatus = "16384";
$returnedMessage = "Time out whilst writing to socket\n";
}
}
This is where I'm experiencing problems. The can_write(30) catches some
errors - EG if I mimic a physically broken WAN connection by unplugging
the server's ethernet cable the client program will time out after 30
seconds and will have set $errorStatus.
But in the event that I close Apache down (presumably this sends a
signla to close the socket on the server side), the client program does
not terminate gracefully. It just stops dead. By dint of putting in
some print statements I've established that the client program never
even gets to the end point of the writeToSocket routine. The program
just stops executing.
So how can I beef up this code to cope better with the circumstances
that I've described?
I have a pair of programs that I use for moving text files (mostly CSV
or XML) around a WAN. I use HTTP to handle the authentication and to
move the data, so the client side program mimics some of the behaviour
of a web browser.
I want to eventually refactor the code (too much global data) but first
I want to make it more robust so that it can handle network or server
failures better.
Note: during a single session I would typically write to and then read
from the same socket. It works well when the WAN connections are good
and the server is up and running, but it doesn't handle some error
conditions well.
In particular I have a problem when sending data and Apache on the
server shuts down. This is an unusual but possible scenario - we might
be shutting the server down for maintenance or because we want to stop
data coming in for whatever reason.
The socket is opened in a subroutine...
sub openSocket{
# first set up the socket timer
$socketTimer = IO::Select->new();
unless($socket = IO::Socket::INET->new(PeerAddr => $remoteSite,
PeerPort => 80,
Proto => "tcp",
Timeout => 10,
Type => SOCK_STREAM)
){
$errorStatus = "8192";
$returnedMessage = "Can't connect to $remoteSite";
print "$localMessage$returnedMessage\n" if ($debug);
}
# add the timer if we connected
$socketTimer->add($socket) unless $errorStatus;
}
All writing to the socket is done through a subroutine too...
sub writeToSocket{
# check socket still open
if($socketTimer->can_write(30)){
syswrite($socket, $oline);
}
else
{
$errorStatus = "16384";
$returnedMessage = "Time out whilst writing to socket\n";
}
}
This is where I'm experiencing problems. The can_write(30) catches some
errors - EG if I mimic a physically broken WAN connection by unplugging
the server's ethernet cable the client program will time out after 30
seconds and will have set $errorStatus.
But in the event that I close Apache down (presumably this sends a
signla to close the socket on the server side), the client program does
not terminate gracefully. It just stops dead. By dint of putting in
some print statements I've established that the client program never
even gets to the end point of the writeToSocket routine. The program
just stops executing.
So how can I beef up this code to cope better with the circumstances
that I've described?