I'm working on a small project using IO::Socket::Async. I'm trying write some tests to make sure I'm handling a connection loss properly but my initial attempts didn't go as planned. I thought using a QUIT phaser would work but that didn't give any response in the tests I tried closing the supply but that isn't giving the results I was hoping for. Can someone point me in the right direction on how to handle a connection loss with IO::Socket::Async?
An example of the supply where I try to use the quit is below. Since it isn't working how I expected. I am not sure if I am going about this correctly.
supply whenever $connection -> $event {
if $event ~~ /event message/ {
emit { status => $event };
}
QUIT {
.note;
say 'conection lost';
}
}
There are two ways a connection might be terminated:
whenever
subscription is much like a loop, and the LAST
phaser triggers on orderly end of the stream. So, to handle this case, use LAST
.QUIT
as you wrote (though you need QUIT { default { note $_ } }
to actually handle it, just as with CATCH
).It seems that quite a few more cases are considered "orderly" (that is, the EOF case) than at least I expected. For example, run a server like this:
react {
whenever IO::Socket::Async.listen('localhost', 4242) -> $conn {
whenever $conn -> $stuff {
$conn.print($stuff);
}
}
}
And a client like this:
my $conn = await IO::Socket::Async.connect('localhost', 4242);
react {
whenever $conn -> $stuff {
say "Got back $stuff";
LAST {
say "Connection closed";
done;
}
QUIT {
default {
say "Connection lost: $_";
done;
}
}
}
whenever Supply.interval(1) {
$conn.print("hello $_\n");
}
}
Then Ctrl+C the server, and - at least on my local setup (Ubuntu in a VM) - it triggered the LAST
. I wondered if this could be some kind of bug, so traced it all the way back into the VM's I/O binding, and no, we really are getting EOF passed to us from the operating system in that case, not an error. Sticking the server on a separate machine, and then disconnecting the wifi on my local one, was enough to trigger the QUIT
case with a "Connection reset by peer".
In summary, QUIT
is the right way to handle erroneous loss of connection, but LAST
is triggered by EOF, and that shows up in some cases that we might consider "connection loss"; only the protocol being spoken atop of the socket can really determine whether this was an unexpected time for things to come to an end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With