Соединение может быть разорвано двумя способами:
- EOF, который мы считаем «упорядоченным» закрытием. Подписка
whenever
очень похожа на цикл, а фазер LAST
срабатывает в упорядоченном конце потока. Итак, чтобы справиться с этим случаем, используйте LAST
.
- Ошибочное завершение, такое как сброс соединения одноранговым узлом, который вызовет
QUIT
, как вы написали (хотя вам нужен QUIT { default { note $_ } }
, чтобы фактически обработать это, как и в случае с CATCH
).
Кажется, что гораздо больше случаев считаются "упорядоченными" (то есть, случай EOF), чем, по крайней мере, я ожидал. Например, запустите сервер следующим образом:
react {
whenever IO::Socket::Async.listen('localhost', 4242) -> $conn {
whenever $conn -> $stuff {
$conn.print($stuff);
}
}
}
И такой клиент:
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");
}
}
Затем Ctrl+C сервер, и — по крайней мере, в моей локальной установке (Ubuntu в виртуальной машине) — это вызвало ошибку LAST
. Я задавался вопросом, может ли это быть какой-то ошибкой, поэтому проследил все это до привязки ввода-вывода виртуальной машины, и нет, в этом случае мы действительно получаем EOF, передаваемый нам из операционной системы, а не ошибка. Вставить сервер на отдельную машину, а затем отключить Wi-Fi на моей локальной машине было достаточно, чтобы вызвать случай QUIT
с «Сбросом соединения по узлу».
Таким образом, QUIT
— это правильный способ справиться с ошибочной потерей соединения, но LAST
запускается EOF, и это проявляется в некоторых случаях, которые мы можем рассматривать как «потерю соединения»; только протокол, о котором говорят поверх сокета, может действительно определить, было ли это неожиданным временем для завершения вещей.
person
Jonathan Worthington
schedule
01.11.2018
LAST { $conn.close ; } QUIT { default { $conn.close ; say "oh no, $_";}} CATCH { default { say .^name, ': ', .Str , " handled in $?LINE";}}
rosettacode.org/ вики/Simple_database#Perl_6 - person Ken Town   schedule 30.10.2018