Информация об изменениях

Сообщение Re[5]: Отладка Boost::Asio от 06.12.2019 16:27

Изменено 06.12.2019 16:38 netch80

Re[5]: Отладка Boost::Asio
Здравствуйте, prrt, Вы писали:

P>Может, изначальная проблема кроется в том, что acceptor перестал делать accept? В этом случае как-то так и должно ведь быть, клиенты остались, а серверные соединения исчезли.


С принудительно проактивным построением ASIO действительно проблема, что если в каком-то случае забыть "взвести курок" на следующий "выстрел", то оно так и останется ничего не делающим — а добиться этого банально: не все ветки исполнения проследил; поймал исключение и не сделал finally (его аналог для C++) для запроса следующего действия по сокету; и так далее.
Спастись от этого можно только дисциплиной кодирования — или дополнительными костылями по всему коду.

У меня в одном проекте работал самопальный аналог ASIO, сделанный по модели питоновского asyncore. В этом случае у объекта — оболочки сокета есть переопределяемые методы readable и writable, которые он дёргает перед каждым циклом ожидания и проверки поступления данных. Там с этим значительно проще: сам фреймворк обязан вызвать эти методы — и он их вызывает, осталось только подставлять правильные данные. Но это почти реактивное построение, а не проактивное.

Думаю, проверить можно так: сделайте где-то переменную (достаточно bool) с логикой типа:

void Zuka::requestAccept() {
  if (mAcceptRequested) { return; }
  mIOService.async_accept(..., [this](const boost::system::error_code &ec) { cbAccept(ec); });
  mAcceptRequested = true;
}
void Zuka::cbAccept(const boost::system::error_code &ec) {
  if (ec) { разберётесь сами; }
  mAcceptRequested = false;
  ... обработка ...
  if (!mShutdownRequested) { requestAccept(); }
}


Тогда в отладчике можно будет проверять этот флаг; не стоит => ошибка в вашем коде; стоит => проблема в ASIO.

P> Правда непонятно, почему asio в этом случае не реагирует на сигналы, зарегистрированные в этом же io_service. Точнее, как попадешь — иногда реагирует, иногда нет.

P>И если так, то по какой причине это может быть? Нигде в логах нет никаких сообщений, никаких ошибок.

Ну в таком сложном звере ошибки вполне возможны. Но это надо ещё доказать.
Re[5]: Отладка Boost::Asio
Здравствуйте, prrt, Вы писали:

P>Может, изначальная проблема кроется в том, что acceptor перестал делать accept? В этом случае как-то так и должно ведь быть, клиенты остались, а серверные соединения исчезли.


С принудительно проактивным построением ASIO действительно проблема, что если в каком-то случае забыть "взвести курок" на следующий "выстрел", то оно так и останется ничего не делающим — а добиться этого банально: не все ветки исполнения проследил; поймал исключение и не сделал finally (его аналог для C++) для запроса следующего действия по сокету; и так далее.
Спастись от этого можно только дисциплиной кодирования — или дополнительными костылями по всему коду.

У меня в одном проекте работал самопальный аналог ASIO, сделанный по модели питоновского asyncore. В этом случае у объекта — оболочки сокета есть переопределяемые методы readable и writable, которые он дёргает перед каждым циклом ожидания и проверки поступления данных. Там с этим значительно проще: сам фреймворк обязан вызвать эти методы — и он их вызывает, осталось только подставлять правильные данные. Но это почти реактивное построение, а не проактивное.

Думаю, проверить можно так: сделайте где-то переменную (достаточно bool) с логикой типа:

void Zuka::requestAccept() {
  if (mAcceptRequested) { return; }
  mIOService.async_accept(..., [this](const boost::system::error_code &ec) { cbAccept(ec); });
  mAcceptRequested = true;
}
void Zuka::cbAccept(const boost::system::error_code &ec) {
  if (ec) { разберётесь сами; }
  mAcceptRequested = false;
  ... обработка ...
  if (!mShutdownRequested) { requestAccept(); }
}


Тогда в отладчике можно будет проверять этот флаг; не стоит => ошибка в вашем коде; стоит => проблема в ASIO.

P> Правда непонятно, почему asio в этом случае не реагирует на сигналы, зарегистрированные в этом же io_service. Точнее, как попадешь — иногда реагирует, иногда нет.

P>И если так, то по какой причине это может быть? Нигде в логах нет никаких сообщений, никаких ошибок.

Ну в таком сложном звере ошибки вполне возможны. Но это надо ещё доказать.

UPD: если и сигналы зависают, то тут что-то более хитрое. Но всё равно стоит попробовать