Обработка ошибок соединения с IO :: Socket :: Async - PullRequest
0 голосов
/ 30 октября 2018

Я работаю над небольшим проектом, используя IO :: Socket :: Async. Я пытаюсь написать несколько тестов, чтобы убедиться, что я правильно обрабатываю потерю соединения, но мои первоначальные попытки не прошли как планировалось. Я думал, что использование фазера QUIT будет работать, но это не дало никакого ответа в тестах, которые я пытался закрыть, но это не дает результатов, на которые я надеялся. Может кто-нибудь указать мне правильное направление о том, как обрабатывать потерю соединения с IO :: Socket :: Async?

Ниже приведен пример предложения, в котором я пытаюсь использовать выход. Так как это не работает, как я ожидал. Я не уверен, правильно ли я поступаю.

supply whenever $connection -> $event {
    if $event ~~ /event message/ {
       emit { status => $event };
    }
    QUIT {
        .note;
        say 'conection lost';
    }
}

1 Ответ

0 голосов
/ 01 ноября 2018

Существует два способа разрыва соединения:

  • EOF, который мы считаем "упорядоченным" закрытием. Подписка whenever очень похожа на цикл, а фазер LAST запускается в упорядоченном конце потока. Итак, для обработки этого случая используйте LAST.
  • Ошибочное завершение, такое как сброс соединения по пиру, который вызовет QUIT, как вы написали (хотя вам нужно QUIT { default { note $_ } }, чтобы фактически обработать это, так же как с CATCH).

Похоже, что еще несколько дел считаются "упорядоченными" (то есть дело EOF), чем ожидалось по крайней мере I . Например, запустите сервер так:

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, и в некоторых случаях это может показаться "потерей соединения"; только протокол, о котором говорится поверх сокета, может действительно определить, было ли это неожиданным временем для того, чтобы что-то закончилось.

...