Re[10]: boost::asio
От: remark Россия http://www.1024cores.net/
Дата: 14.01.08 10:44
Оценка:
Здравствуйте, Left2, Вы писали:

R>>Основное — использование кодов возврата Ну натурально кода в 2 раза больше получается. В принципе это мой личный пунктик по поводу объёма кода, я знаю, что многих это смущает значительно меньше.

L>Специфика Во-1, это поддержка кучи платформ/компиляторов, многие из которых с исключениями не дружат... Во-2 — исключения зачастую дОроги, а в такой библиотеке понять где штатная ситуация а где реально исключительная — тяжеловато


Я понимаю, что ACE ближе в АПИ ОС... Но если бы они пошли до-конца, то тогда бы надо писать на С и не использовать шаблоны.
И всё-таки, я думаю, что при ошибке при выделении памяти или создании сокета вполне уместно использовать исключение...



R>>Ну и так по-мелочам — шаблоны бы там могли использовать более экстенсивно.

L>Тоже вроде как специфика поддержки сирых и убогих компиляторов.

AFAIK шаблоны там всё же в некоторых местах используются. Да, точно. Причём не в паре мест.


R>>

L>В любом случае — спасибо, было интересно почитать отзыв.

1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: boost::asio
От: Left2 Украина  
Дата: 14.01.08 10:53
Оценка:
R>Я понимаю, что ACE ближе в АПИ ОС... Но если бы они пошли до-конца, то тогда бы надо писать на С и не использовать шаблоны.
Тогда бы вместе с водой выплеснули бы и ребёнка. Шли на компромисс.

R>>>Ну и так по-мелочам — шаблоны бы там могли использовать более экстенсивно.

L>>Тоже вроде как специфика поддержки сирых и убогих компиляторов.
R>AFAIK шаблоны там всё же в некоторых местах используются. Да, точно. Причём не в паре мест.
Да, используются — но они стараются делать их максимально простыми, типа как std::vector — только для типизации и не боле.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[11]: boost::asio
От: siv Украина  
Дата: 14.01.08 11:08
Оценка:
R>Если библиотека не умеет элегантно обрабатывать затык сети, а, например, просто тупо жрёт всю доступную память, то от использующего уже ничего не зависит — он даже не заметит, что то-то идёт не так.

Согласен на все 100. Но хотелось бы знать, что ты понимаешь "под затыком в сети" с точки зрения библиотеки?
Мы ж говорим о библиотеке над сокетами, а не для написания TCP/IP стека, верно?
Я на "затыки" сейчас смотрю глазами пользователя asio и её подход меня вполне устраивает.

R>Я верю, что в ACE есть средства для обработки таких ситуаций...

Мне просто интересно, о каких ты конкретно говоришь ситуациях и как их, с твоей точки зрения может решать или не решать библиотека.
Re[11]: boost::asio
От: siv Украина  
Дата: 14.01.08 11:34
Оценка:
L>>Специфика Во-1, это поддержка кучи платформ/компиляторов, многие из которых с исключениями не дружат...
IMHO, таких компиляторов уже меньшинство, если мы не говорим о какой-то embedded экзотике. О, читал, что компилятор для Simbian не поддерживает exceptions. Но и ACE на Simbian вроде не портирован...
L>>Во-2 — исключения зачастую дОроги
Мне кажется, что это мнение устарело несколько. Нет, конечно можно сделать исключения очень дорогими (e.g. сделать дорогим конструктор, ...), но зачем? Тем не менее, плюсов от их использования масса.

Мне, например, импонирует подход asio. Как правило, там присутствует пара схожих функций, одна просто кидает исключение, вторая может передать "наверх" error-объект. Этот объект далее может быть использован т.о.:
error err;
DoWhatever( a,b,c, err ); // тут err передается по ссылке
if ( err )
{
  // error handling here
}

Т.е. хочешь, используй так, а хочешь, как выше:
try
{
  DoWhatever( a,b,c );
}
catch ( error const & err )
{
  // error handling here
}


R>И всё-таки, я думаю, что при ошибке при выделении памяти или создании сокета вполне уместно использовать исключение...

И ты не одинок


R>>>Ну и так по-мелочам — шаблоны бы там могли использовать более экстенсивно.

L>>Тоже вроде как специфика поддержки сирых и убогих компиляторов.
Ну, вот это одна из причин, по которой можно считать ACE устаревшей.

R>AFAIK шаблоны там всё же в некоторых местах используются. Да, точно. Причём не в паре мест.

Чуть-чуть беремены?
Re[12]: boost::asio
От: Left2 Украина  
Дата: 14.01.08 12:14
Оценка:
L>>>Специфика Во-1, это поддержка кучи платформ/компиляторов, многие из которых с исключениями не дружат...
siv>IMHO, таких компиляторов уже меньшинство, если мы не говорим о какой-то embedded экзотике. О, читал, что компилятор для Simbian не поддерживает exceptions. Но и ACE на Simbian вроде не портирован...
Портировать что-то на симбиан (особенно версий младше 9-ки) это вообще оччень трудоёмкая задача (разве что заранее проектировать с учётом специфики этой платформы).

L>>>Во-2 — исключения зачастую дОроги

siv>Мне кажется, что это мнение устарело несколько. Нет, конечно можно сделать исключения очень дорогими (e.g. сделать дорогим конструктор, ...), но зачем? Тем не менее, плюсов от их использования масса.
К примеру, MSVC бросает С++-исключения через SEH. Это тысячи тактов в релизе, миллионы в Debug и десятки миллионов в Debug при подключённом отладчике. Можно конечно отказаться от дебажных билдов, но как-то это уж черезчур... Я понимаю что на исключениях нельзя строить логику, но как раз ACE построена вокруг таких мест где очень тяжело различить штатную и исключительную ситуацию. К примеру (условно), если получение битого пакета при нормальной работе это исключительная ситуация (и тут исключения замечательно упрощают логику) то при ДОС-атаке это превращается в ситуацию штатную.

R>>AFAIK шаблоны там всё же в некоторых местах используются. Да, точно. Причём не в паре мест.

siv>Чуть-чуть беремены?
Шаблоны можно очень сильно по-разному использовать, аналогия про беременность тут никак не подходит.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[12]: boost::asio
От: remark Россия http://www.1024cores.net/
Дата: 14.01.08 13:44
Оценка:
Здравствуйте, siv, Вы писали:

R>>Если библиотека не умеет элегантно обрабатывать затык сети, а, например, просто тупо жрёт всю доступную память, то от использующего уже ничего не зависит — он даже не заметит, что то-то идёт не так.


siv>Согласен на все 100. Но хотелось бы знать, что ты понимаешь "под затыком в сети" с точки зрения библиотеки?

siv>Мы ж говорим о библиотеке над сокетами, а не для написания TCP/IP стека, верно?
siv>Я на "затыки" сейчас смотрю глазами пользователя asio и её подход меня вполне устраивает.

R>>Я верю, что в ACE есть средства для обработки таких ситуаций...

siv>Мне просто интересно, о каких ты конкретно говоришь ситуациях и как их, с твоей точки зрения может решать или не решать библиотека.


Допустим сервер проксирования голоса. Сокет может отсылать данные очень медленно. А данные, которые надо на него отправить, приходят быстро. Библиотека должна позволять контролировать суммарный объём данных, который ждёт отправки на данный сокет. Что бы медленный сокет не приводил к съеданию всей памяти. Наиболее реалистичная стратегия — убивать наиболее старые данные, которые стоят в очереди на отправку.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: boost::asio
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 15.01.08 09:06
Оценка: 6 (1)
Здравствуйте, remark, Вы писали:

R>>>Я имею в виду не производительность. А больше то, насколько часто серверу позволено падать Насколько он должен переживать перегрузку сети, нехватку памяти и т.д.

siv>>Ну тут уже многое (бОльшее?) от использующего булиотеку будет зависеть.


R>Если библиотека не умеет элегантно обрабатывать затык сети, а, например, просто тупо жрёт всю доступную память, то от использующего уже ничего не зависит — он даже не заметит, что то-то идёт не так. Я верю, что в ACE есть средства для обработки таких ситуаций...


В ACE защита от перегрузки приложения строится на уровне класса ACE_Message_Queue. В нем определены понятия high_water_mark и low_water_mark. Параметр high_water_mark определяет максимальное количество сообщений, которое можно поместить в очередь без блокировки. Когда же в очереди оказывается слишком много сообщений, то при попытке поместить очередное сообщение нить засыпает на вызове enqueue.

Т.е., если есть Producer и Consumer, связанные одной Message_Queue, то Producer будет засыпать на enqueue, если Consumer не будет успевать выбирать сообщения из очереди.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: boost::asio
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 15.01.08 09:09
Оценка:
Здравствуйте, siv, Вы писали:

siv>А подобные куски напоминают слова из песни — "и никто не узнает где могилка его":

siv>
siv>SocketIOS::~SocketIOS()
siv>{
siv>    try
siv>    {
siv>        _buf.sync();
siv>    }
siv>    catch (...)
siv>    {
siv>    }
siv>}
siv>


А здесь-то что плохого? Деструкторы не должны выпускать исключений. В случаях, когда все методы библиотеки генерят исключения (в том числе и _buf.sync()), это нормальный способ обеспечить работу деструктора.

Или нужно было в catch-е abort() вызвать?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: boost::asio
От: siv Украина  
Дата: 15.01.08 09:27
Оценка:
siv>>А подобные куски напоминают слова из песни — "и никто не узнает где могилка его":
siv>>
siv>>SocketIOS::~SocketIOS()
siv>>{
siv>>    try
siv>>    {
siv>>        _buf.sync();
siv>>    }
siv>>    catch (...)
siv>>    {
siv>>    }
siv>>}
siv>>


E>А здесь-то что плохого? Деструкторы не должны выпускать исключений. В случаях, когда все методы библиотеки генерят исключения (в том числе и _buf.sync()), это нормальный способ обеспечить работу деструктора.

Довольно грязный метод обеспечения безопасности исключений. После такого тихого поглощения исключения состояние программы может стать несогласованным и ошибка вылезет намного позже неизвестно где и будет довольно тяжело понять откуда ноги растут.

E>Или нужно было в catch-е abort() вызвать?

Нет. Просто (хотя это и не всегда просто) написать безопасный деструктор.
В данном случае, по-видимому, нужно делать exception-о небезопасный cleanup не в деструкторе.
Но, если дизайн таков, что это затруднительно, то такой дизайн мне и не нравится.
Могу только предполагать, что делает _buf.sync() и какие методы есть у _buf,
но мне, как вариант, больше бы понравилось:
SocketIOS::~SocketIOS()
{
    // The buffer is not synced! Provide it anywhere before the object is being destroyed.
    assert( _buf.IsSynced() );
}
Re[9]: boost::asio
От: remark Россия http://www.1024cores.net/
Дата: 15.01.08 09:33
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, siv, Вы писали:


siv>>А подобные куски напоминают слова из песни — "и никто не узнает где могилка его":

siv>>
siv>>SocketIOS::~SocketIOS()
siv>>{
siv>>    try
siv>>    {
siv>>        _buf.sync();
siv>>    }
siv>>    catch (...)
siv>>    {
siv>>    }
siv>>}
siv>>


E>А здесь-то что плохого? Деструкторы не должны выпускать исключений. В случаях, когда все методы библиотеки генерят исключения (в том числе и _buf.sync()), это нормальный способ обеспечить работу деструктора.


E>Или нужно было в catch-е abort() вызвать?



+1
Или например в деструкторе надо что-то залогировать. А логирование скорее всего может кидать исключения, т.к. затрагивает аллокацию памяти.
Уж лучше подавить исключение... вместе с логированием, чем убить программу...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: boost::asio
От: remark Россия http://www.1024cores.net/
Дата: 15.01.08 09:35
Оценка:
Здравствуйте, siv, Вы писали:

E>>А здесь-то что плохого? Деструкторы не должны выпускать исключений. В случаях, когда все методы библиотеки генерят исключения (в том числе и _buf.sync()), это нормальный способ обеспечить работу деструктора.

siv>Довольно грязный метод обеспечения безопасности исключений. После такого тихого поглощения исключения состояние программы может стать несогласованным и ошибка вылезет намного позже неизвестно где и будет довольно тяжело понять откуда ноги растут.


А если например надо что-то залогировать в деструкторе, а логирование может потенциально кидать исключения. Что ты предлагаешь делать?



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: boost::asio
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 15.01.08 09:38
Оценка:
Здравствуйте, siv, Вы писали:

E>>А здесь-то что плохого? Деструкторы не должны выпускать исключений. В случаях, когда все методы библиотеки генерят исключения (в том числе и _buf.sync()), это нормальный способ обеспечить работу деструктора.

siv>Довольно грязный метод обеспечения безопасности исключений. После такого тихого поглощения исключения состояние программы может стать несогласованным и ошибка вылезет намного позже неизвестно где и будет довольно тяжело понять откуда ноги растут.

Да уж...

E>>Или нужно было в catch-е abort() вызвать?

siv>Нет. Просто (хотя это и не всегда просто) написать безопасный деструктор.
siv>В данном случае, по-видимому, нужно делать exception-о небезопасный cleanup не в деструкторе.
siv>Но, если дизайн таков, что это затруднительно, то такой дизайн мне и не нравится.
siv>Могу только предполагать, что делает _buf.sync() и какие методы есть у _buf,
siv>но мне, как вариант, больше бы понравилось:
siv>
siv>SocketIOS::~SocketIOS()
siv>{
siv>    // The buffer is not synced! Provide it anywhere before the object is being destroyed.
siv>    assert( _buf.IsSynced() );
siv>}
siv>


Т.е. по вашему, нужно, чтобы пользователь явно вызывал какой-то метод cleanup(), а деструктор просто проверял, что этот cleanup() был вызван? И тогда код должен выглядеть как-то так:
void f()
  {
    try
      {
        SocketIOS socket( ... );
        ...
        socket.close();
      }
    catch( ... )
      {
        socket.cleanup();
        throw;
      }
  }


Я правильно вас понял?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: boost::asio
От: siv Украина  
Дата: 15.01.08 10:10
Оценка:
О, ну вам бы пофлеймить бы только
Мне кажется, что мы уже и так сильно отклонились от заданной в исходном посте темы.

E>Т.е. по вашему, нужно, чтобы пользователь явно вызывал какой-то метод cleanup(), а деструктор просто проверял, что этот cleanup() был вызван?

Еще раз повторю, я не знаю что такое SocketIOS конкретно, какие у него ограничения и вообще с чем его едят.
Я не пытался привести универсальное решение для всех случаев жизни.
Мне резануло глаз, что в POCO очень часто используется catch( ... ).
Да, в основном в деструкторах, но это все-равно грязная практика.

E> И тогда код должен выглядеть как-то так:

E>
E>void f()
E>  {
E>    try
E>      {
E>        SocketIOS socket( ... );
E>        ...
E>        socket.close();
E>      }
E>    catch( ... )
E>      {
E>        socket.cleanup();
E>        throw;
E>      }
E>  }
E>


E>Я правильно вас понял?

Если кратко, то нет, не правильно
Подумайте, где уместнее видеть "cleanup();" (возможно, совсем не тривиальный внутри) ?
Re[12]: boost::asio
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 15.01.08 10:15
Оценка:
Здравствуйте, siv, Вы писали:

siv>О, ну вам бы пофлеймить бы только

siv>Мне кажется, что мы уже и так сильно отклонились от заданной в исходном посте темы.

На пофлеймить у меня времени нет, а то бы я с удовольствием.

Дело в другом: я пытаюсь учиться. И когда я вижу, что используемый мной подход чем-то плох, то пытаюсь узнать чем же он плох и как это исправить.

Вы говорите, что перехват и подавление всех исключений в деструкторе -- это грязная практика. Хочется понять почему и что лучше использовать вместо этого.

E>> И тогда код должен выглядеть как-то так:

E>>
E>>void f()
E>>  {
E>>    try
E>>      {
E>>        SocketIOS socket( ... );
E>>        ...
E>>        socket.close();
E>>      }
E>>    catch( ... )
E>>      {
E>>        socket.cleanup();
E>>        throw;
E>>      }
E>>  }
E>>


E>>Я правильно вас понял?

siv>Если кратко, то нет, не правильно
siv>Подумайте, где уместнее видеть "cleanup();" (возможно, совсем не тривиальный внутри) ?

По мне, так здесь нужно писать всего лишь:
void f()
  {
    SocketIOS socket( ... );
    ...
  }

без явных вызовов close()/cleanup() и try/catch.

А как по вашему?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: boost::asio
От: siv Украина  
Дата: 15.01.08 10:22
Оценка:
R>А если например надо что-то залогировать в деструкторе, а логирование может потенциально кидать исключения. Что ты предлагаешь делать?
Относительно данного случая ничего не имею против
Но "_buf.sync();" как-то слабо похож на на безобидное логирование.
Тем более, если sync, предположим, виртуальный, ожидать от него exception safety вообще сложно.
Но это не повод, IMHO, молча глотать все исключения, вместо того, чтобы его вставить в другое более подходящее место...
Согласны?
Re[13]: boost::asio
От: siv Украина  
Дата: 15.01.08 10:25
Оценка:
E>По мне, так здесь нужно писать всего лишь:
E>
E>void f()
E>  {
E>    SocketIOS socket( ... );
E>    ...
E>  }
E>

E>без явных вызовов close()/cleanup() и try/catch.

E>А как по вашему?

И по-моему. При нормальном дизайне SocketIOS.
Re[13]: boost::asio
От: siv Украина  
Дата: 15.01.08 10:41
Оценка:
R>>>Я верю, что в ACE есть средства для обработки таких ситуаций...
siv>>Мне просто интересно, о каких ты конкретно говоришь ситуациях и как их, с твоей точки зрения может решать или не решать библиотека.


R>Допустим сервер проксирования голоса. Сокет может отсылать данные очень медленно. А данные, которые надо на него отправить, приходят быстро. Библиотека должна позволять контролировать суммарный объём данных, который ждёт отправки на данный сокет. Что бы медленный сокет не приводил к съеданию всей памяти. Наиболее реалистичная стратегия — убивать наиболее старые данные, которые стоят в очереди на отправку.


Ну, мне кажется, мы немного о разном.
В исходном вопросе, по-моему, больше интересовала библиотека работы с сокетами, а не библиотека построения proxy для голоса
Что касается asio, то помимо работы только с сокетами, есть и небольшие утилитарные классы, в т.ч. и для буферизации. Но последний я не использую, именно чтобы специфически решать в т.ч. упомянутую проблему немного выше уровнем.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.