event driven - зло или несовсем? (и чуть-чуть QT or not QT?)

kokoc88

Всё, наболело, не могу больше отмалчиваться про Qt.
С одной стороны это, конечно, кроссплатформенный тулкит для написания софта на Си++: там есть и GUI, и сокеты, и подсчёт криптографического хэша, и строки аж с поддержкой трансляции байтов в различных кодовых страницах, и потоки.
Теперь поговорим о недостатках. :mad: Я привожу только часть из них, но практически все они вводят меня в ступор.
1. Мне кажется, что если начать работать в рамках этого тулкита, то выйти за них уже очень сложно. Либо всё на Qt, либо ничего. Это само по себе poor design.
2. Разработчики на Qt имеют какую-то маниакальную приверженность к event driven programming. Даже для двух объектов, которые агрегированы и работают в паре в одном потоке, пишется event driven управление. Причём соединения сигналов и слотов происходят обычно в разных файлах так, что приходится сделать full text search по проекту несколько раз, прежде чем поймёшь, как это всё работает. Вместо любого архитектурного решения разработчиками, привыкшими к Qt, сразу же предлагается соединить два класса через слот-сигнал.
3. При работе с Qt надо пользоваться потоками из Qt, что является poor design. Если этого не делать, то поведение Qt классов варьируется от спама дебаг сообщений до access violation.
4. Некоторые Qt объекты, которые созданы в одном потоке, нельзя удалять в другом. Деструктор вполне может вызвать terminate через qt_assert. Такой дизайн библиотеки для разработки софта можно было придумать только с сильного перепоя.
5. Qt Socket - это вообще отдельная песня. Я даже не знаю, что можно написать про такое гавно. В одном Qt потоке может жить только один Qt сокет. Если не следовать этому правилу, то поведение программы варьируется от полной работоспособности, до спама дебаг сообщений и access violation. Из сокета можно либо читать, либо туда писать. Только из одного потока. Вызов функций сокета в разных потоках приводит к... ну вы уже догадались, к чему.
Edit: В разных потоках можно использовать один сокет. Остальные проблемы остаются.

slonishka

и, насколько я понимаю, к 4 версии все стало только хуже?

hashion

В одном Qt потоке может жить только один Qt сокет.
О да... Если у вас даже не получается запустить в одном потоке несколько qt-сокетов - может стоит сметь профессию?

kokoc88

и, насколько я понимаю, к 4 версии все стало только хуже?
Без понятия, я это чудо начал тискать с версии 4.0.1

kokoc88

О да... Если у вас даже не получается запустить в одном потоке несколько qt-сокетов - может стоит сметь профессию?
Без понятия, не получается у коллеги. Кажется, Qt что-то спамит в debug окно. Это не отменяет других пунктов, которые, очевидно, poor designed.

hashion

не получается у коллеги
А у тебя получается?

kokoc88

А у тебя получается?
Я не пробовал. Но использовать Qt сокет синхронно - пробовал. Никому этого не пожелаю.

hashion

Я не пробовал.
Так вот в чём проблема.
Но использовать Qt сокет синхронно - пробовал. Никому этого не пожелаю.
Дык может нужно было запустить его Асинхронно, чтобы он не мешал работать другим?

void Server::initSocket
{
udpSocket = new QUdpSocket(this);
udpSocket->bind(QHostAddress::LocalHost, 7755);

connect(udpSocket, SIGNAL(readyRead
this, SLOT(readPendingDatagrams;
}

void Server::readPendingDatagrams
{
while (udpSocket->hasPendingDatagrams {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize;
QHostAddress sender;
quint16 senderPort;

udpSocket->readDatagram(datagram.data datagram.size
&sender, &senderPort);

processTheDatagram(datagram);
}
}

Красота, даже беркли-сокеты отдыхают.

kokoc88

Дык может нужно было запустить его Асинхронно, чтобы он не мешал работать другим?
Зачем мне запускать его асинхронно, когда я адаптировал его для пакета, который работает с сокетами синхронно и никому не мешает? Не все программисты приверженцы пихания event driven подхода во все возможные дыры, чтобы программа заодно была менее читабельной.

hashion

который работает с сокетами синхронно и никому не мешае
тогда объясни, как в одном треде делаешь синхронную запись/чтения без event-driven?

kokoc88

тогда объясни, как в одном треде делаешь синхронную запись/чтения без event-driven?
Очень просто: протокол запрос-ответ. Асинхронность реализации этого протокола никому никуда не впилась. Qt вместо этого предлагает засунуть в рот ноги и всё равно прикрутить event driven. Это poor design of network library. Мне не известно других сетевых библиотек, которые не позволяют простые проблемы решать просто. Тоже самое касается и необходимости делать это всё в одном потоке, тогда как запись и чтение можно делать из разных потоков одновременно, повышая производительность системы.

Werdna

Есть libevent для работы с сетью.
Работать с сетью без событийной машины — зло.

kokoc88

Работать с сетью без событийной машины — зло.
Протокол запрос-ответ не нуждается в эвентах.
И, кроме того, даже потоковые протоколы не нуждаются в эвентах на уровне сокета. Удобнее читать синхронно, производить анализ и преобразование потока байтов в поток объектов, и уже по факту появления новго объекта посылать сообщения.

Werdna

Протокол запрос-ответ не нуждается в эвентах.

Это неправда.
ты будешь ждать при чтении после accept и просасывать?
И, кроме того, даже потоковые протоколы не нуждаются в эвентах на уровне сокета

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

slonishka

можно вообще писать в стиле каком угодно
ну ему же не нравится как раз то, что qt не позволяет "как угодно".
типа забили на ленивых — значит poor design. =)

Werdna

Короче, моя мысль: не надо чтобы Qt было чем-то кроме графики.
Просто потому что если напишешь проект на Qt, то потом с сетевое поделие не сделаешь быстро консольным — придется тащить всё Qt.
Не надо универсальных библиотек.

kokoc88

Это неправда.
ты будешь ждать при чтении после accept и просасывать?
Да, я буду ждать при чтении. Точно так же, как очередь эвентов будет ждать, пока не придёт эвент. Только в моём случае течение программы не будет прерываться на ожидание эвента с сохраненим промежуточного состояния объекта.
Потоковые протоколы идут нахуй. Вернее, ты можешь обрабатывать все потоково, но работа с сетью должна производиться в одном потоке.
Опять же, мелкие ненагруженные приложения можно вообще писать в стиле каком угодно.
Работа с сетью никому ничего не должна. Я могу параллельно посылать файл и принимать сообщения. Если запихать эти два независимых действия в один поток, то логика программы сильно усложнится.

kokoc88

ну ему же не нравится как раз то, что qt не позволяет "как угодно".
типа забили на ленивых — значит poor design. =)
Лень тут не при чём. Я не понимаю, зачем для реализации простого действия требуется сделать десяток сложных.

hashion

Очень просто: протокол запрос-ответ. Асинхронность реализации этого протокола никому никуда не впилась.
Вот из-за таких синхронных cool design и происходят тормоза сетевых приложений. Тот же стим не исключение.
Даже если выделяется один тред на одно соединение обработка всех событий просто необходима: тайм-ауты, внештатные ситуации и т.д. Синхронное чтение/запись - это блокировка треда.
Но если уж совсем хочется - ну запускай тред QT и делайте что хотите - обычный поток. Никто не принуждает пользоваться qtnetwork.
Тоже самое касается и необходимости делать это всё в одном потоке, тогда как запись и чтение можно делать из разных потоков одновременно, повышая производительность системы.
О да, в вашем случае это особенно актуально.

hashion

Просто потому что если напишешь проект на Qt, то потом с сетевое поделие не сделаешь быстро консольным — придется тащить всё Qt.
Да ничего страшного нет в этом. QTNetwork весит 300Кб в полном фарше, один файл.
Приложение легко делается консольным.
Qt - это прежде всего QtCore - не завязано на графику. Графика - QtGui, по сути опциональная.
Вобще суть в другом. QtNetwork позволяет работать асинхронно с сокетами в одном потоке с графикой. И это очень хорошо - нет заморочек с тредами и вобще вероятности ошибки, необходимости синхронизироваться по доступу к памяти и т.д.
Использовать другую библиотеку так не получится, не потому, что QT такой плохой, а потому что всё завязано основной loop обработки событий графической подсистемы (X11, Windows). Графика всегда будет на событиях, ну а синхронные сокеты в графике - это конкретные зависания.
Но ничто не мешает запустить тред и работать с обычными сокетами.
Если ты работаешь только с Qt - это гарантия того, что твой код будет корректно работать на всех плафтормах. Qtnetwork - не исключение. И это очень здорово.

kokoc88

Вот из-за таких синхронных cool design и происходят тормоза сетевых приложений. Тот же стим не исключение.
Даже если выделяется один тред на одно соединение обработка всех событий просто необходима: тайм-ауты, внештатные ситуации и т.д. Синхронное чтение/запись - это блокировка треда.
Не путай реализацию протокола и архитектуру программы. Для реализации неблокирующего GUI вовсе необязательно использовать асинхронный сокет, зачастую порождая больше непонятного кода, чем это на самом деле необходимо. И, представь себе, все таймауты и внештатные ситуации прекрасно обрабатываются и без эвентов прямо на месте, где стоит запрос. Но, как я уже отметил, привыкшие к Qt программисты везде пихают эвенты, стремясь наделать столько дыр в program flow, сколько их в ситичке для чая.
Но если уж совсем хочется - ну запускай тред QT и делайте что хотите - обычный поток. Никто не принуждает пользоваться qtnetwork.
Я уж лучше запущу тред из буста. Но увы, Qt объектам нужен Qt тред. Кроме того, никто не хочет тянуть в программу десятки сторонних библиотек.
Тоже самое касается и необходимости делать это всё в одном потоке, тогда как запись и чтение можно делать из разных потоков одновременно, повышая производительность системы.
--------------------------------------------------------------------------------
О да, в вашем случае это особенно актуально.
Да, в нашем случае это актуально. У нас есть реализация нескольких протоколов.

kokoc88

Вобще суть в другом. QtNetwork позволяет работать асинхронно с сокетами в одном потоке с графикой.
Угу. То есть, если я буду принимать сжатый zip поток данных, то скорость отклика GUI будет обратно пропорциональна скорости передачи данных по сети.

kokoc88

Если ты работаешь только с Qt - это гарантия того, что твой код будет корректно работать на всех плафтормах. Qtnetwork - не исключение. И это очень здорово.
Кстати, что на счёт остальных недостатков?

hashion

Угу. То есть, если я буду принимать сжатый zip поток данных, то скорость отклика GUI будет обратно пропорциональна скорости передачи данных по сети.
Считывай и распаковывай zip-поток небольшими кусками и отдавай управление в loop - всё будет ok.
Вот как раз в синхронном варианте - это целая беда.
Пришло много данных - а деваться некуда, нельзя откладывать.

Dasar

Считывай и распаковывай zip-поток небольшими кусками и отдавай управление в loop - всё будет ok.
руками организовывать кооперативную многозадачность?
и нахрен это надо?
что мы с этого получаем, кроме удорожания разработки?
ps
имхо, асинхронные решения нужны только в тех случаях, когда одновременно задач необходимо выполнять больше, чем разумное число тредов
во всех остальных случаях - лучше отдельные треды с синхронными запросами, чем все эти event driven замуты.

kokoc88

Считывай и распаковывай zip-поток небольшими кусками и отдавай управление в loop - всё будет ok.
Во-первых, это не поможет. Загруженная работой очередь сообщений для GUI в любом случае понизит отклик (responsibility).
Во-вторых, зачем мне вводить какие-то небольшие куски, которые надо хранить как промежуточное состояние объекта, если бы я мог вообще реализовать весь протокол в виде отдельного объекта с асинхронным доступом только в тех местах, в которых это надо.
Вот пример псевдокода, о чём я говорю. Здесь пример реализации логина по протоколу POP3 с использованием синхронного сокета. Сам объект, реализующий протокол, может быть асинхронным. Напиши псевдокод, который переводит эту модель с синхронного чтения и pop на event driven и push.

std::string response;
m_pstrm->receive_message(response);
if (!response_ok(response
throw pop3_error("connection failed");
m_pstrm->send_message("USER " + user);
m_pstrm->receive_message(response);
if (!response_ok(response
throw auth_error("bad username");
m_pstrm->send_message("PASS " + pass);
m_pstrm->receive_message(response);
if (!response_ok(response
throw auth_error("bad password");

Werdna

Вобще суть в другом. QtNetwork позволяет работать асинхронно с сокетами в одном потоке с графикой. И это очень хорошо
Да, тогда я пожалуй соглашусь что это круто. Написание гуи с возможностью делать сетевые вещи.
Скорее мысль которуя я хотел донести — без гуи не надо использовать Qt.

Werdna

Считывай и распаковывай zip-поток небольшими кусками и отдавай управление в loop - всё будет ok.
Вот как раз в синхронном варианте - это целая беда.
Не, ерунжу говоришь.
Надо всего лишь запустить тред распаковки и ему передавать все что пришло. :)

kokoc88

Надо всего лишь запустить тред распаковки и ему передавать все что пришло.
А ещё лучше, чтобы этот поток работал с одним объектом, который делает все эти действия последовательно без эвентов.

Werdna

А ещё лучше, чтобы этот поток работал с одним объектом, который делает все эти действия последовательно без эвентов.
заебали вы своими объектами.
нету никаких объектов. ООП на помойку.

hashion

Надо всего лишь запустить тред распаковки и ему передавать все что пришло. :)
А вот не факт.
Если, конечно, пишется аналог Download Master-a или skype, то да, причём в новый тред запихивать все соединения, нет смысла запускать распаковку в разных тредах, это не спасёт.
А вот к примеру icq, jabber, банк-клиент, тот же steam... Тоже zip может быть или шифрование. Тогда лучше иметь одно соединение с сервером в одном процессе с графикой, это сильно упрощает конструкцию.
Особенно в случае запрос-ответ.
В QT есть хороший пример - QHttp. Отличный пример грамотной организации протокола - составил запрос и забыл. Тебе сообщат уже когда будет готов ответ. Да, машина состояний, но она вся целиком в этом классе, никакой головной боли и никаких блокировок.

Dasar

Хороший пример организации протокола - составил запрос и забыл. Тебе сообщат уже когда будет готов ответ. Да, машина состояний, но она вся целиком в этом классе, никакой головной боли и никаких блокировок.
дык, в синхронном модели - еще все проще, вызвал и забыл, как выполнится - так тебе управление и вернут.

hashion

руками организовывать кооперативную многозадачность?
и нахрен это надо?
что мы с этого получаем, кроме удорожания разработки?
Удорожание - это когда появляются треды.
Тогда нужно между ними организовывать message-passing, а это намного сложнее.
Пример:
Тайм-аут по соединению, полученый в одном треде (event-driven) будет тут же обработан графикой.
В случае тредов - он будет обработан отдельным тредом, передан в основной, и уже потом основным.

hashion

дык, в синхронном модели - еще все проще, вызвал и забыл, как выполнится - так тебе управление и вернут.
Если это работает в одном потоке с графикой - пользователь будет очень часто лихорадочно клацкать мышкой по крестику и материть разработчиков.

Dasar

нету никаких объектов. ООП на помойку.
с каких это пор тред перестал быть объектом?

Dasar

Если это работает в одном потоке с графикой - пользователь будет очень часто лихорадочно клацкать мышкой по крестику и материть разработчиков.
а зачем это делать в том же потоке?

hashion

а зачем это делать в том же потоке?
Уже написал.

kokoc88

вот к примеру icq, jabber, банк-клиент, тот же steam... Тоже zip может быть или шифрование. Тогда лучше иметь одно соединение с сервером в одном процессе с графикой, это сильно упрощает конструкцию.
Особенно в случае запрос-ответ.
В QT есть хороший пример - QHttp. Отличный пример грамотной организации протокола - составил запрос и забыл. Тебе сообщат уже когда будет готов ответ. Да, машина состояний, но она вся целиком в этом классе, никакой головной боли и никаких блокировок.
Ты просто подтверждаешь мои слова: люди, привыкшие к Qt всё путают и делают сложнее, чем требуется. Ещё раз повторю: я хочу сделать свой протокол. Использовать при его реализации асинхронные сокеты невыгодно. При этом никто не мешает объекту этого протокола быть асинхронным и даже общаться с GUI через эвенты.
Ты так и не преобразовал мой псевдокод логина в POP3 в такой же, но на event driven модели. Мне кажется, что если ты это сделаешь, то мои возражения станут более чем очевидными.

kokoc88

Пример:
Тайм-аут по соединению, полученый в одном треде (event-driven) будет тут же обработан графикой.
В случае тредов - он будет обработан отдельным тредом, передан в основной, и уже потом основным.
В случае event driven без потоков эвент таймаута будет положен в очередь для GUI и обработан в соотв. функции. В случае с потоком поток положит точно такой же эвент в точно такую же очередь GUI.

hashion

Ты так и не преобразовал мой псевдокод логина в POP3 в такой же, но на event driven модели. Мне кажется, что если ты это сделаешь, то мои возражения станут более чем очевидными.
Не заметил сообщение:
  
class QPop {
private:
enum State {
NONE,
CONNECTED,
LOGIN_OK_RECV,
PASS_OK_RECV,
} state;

void OnConnect {
state = CONNECTED;
SendMsg (...);
}

void OnMsgRecv (const QString&) {
if (state == NONE) {
// Анализ полученных данных, ошибки и т.д.
state = LOGIN_OK_RECV;
SendMsg (...);
}
if (state == LOGIN_OK_RECV) {
// Анализ полученных данных, ошибки и т.д.
state = PASS_OK_RECV;
emit Result ;
}
}

public:
QPop (const QString& server, const QString& login, const QString& pass) : state (NONE)
{// Устанавливается соединение }
signals:
void Result ;

};

QPop* qpop = new QPop ("pop.mail.ru", "login", "password");
connect (qpop, Result ...);


В чём плюс:
* Выглядит посложнее, чем ты привёл, но сделай протокол чуть хитрее и использование статусов себя оправдвает.
* Никаких тредов, а это уже очень большой плюс.
* Пишется и отлаживается один раз всё это хозяйство - потом только используешь. Состояния не перемешиваются с состояниями класса.

hashion

В случае event driven без потоков эвент таймаута будет положен в очередь для GUI и обработан в соотв. функции.
Вот, проброс евентов через треды.
А потом люди удивляются - а чтож у меня всё валится и как это отлаживать.

Dasar

Вот, проброс евентов через треды.
А потом люди удивляются - а чтож у меня всё валится и как это отлаживать.
event driven - чаще дохнет, т.к. в event driven очень сложно отслеживать и data flow, и control flow.
соответственно, довольна частая ошибка, что данные уже грохнули или еще не создали, а обращение к ним уже идет.

kokoc88

В чём плюс:
* Выглядит посложнее, чем ты привёл, но сделай протокол чуть хитрее и использование статусов себя оправдвает.
* Никаких тредов, а это уже очень большой плюс.
* Пишется и отлаживается один раз всё это хозяйство - потом только используешь. Состояния не перемешиваются с состояниями класса.
Зачем делать POP3 протокол хитрее? Он ровно такой, каким описан в RFC1939. Кроме того хочу заметить, что во-первых тебе следовало использовать State паттерн. Ещё раз подтвердили правило, что разработчики Qt видят во всём только эвенты. Во-вторых ты затрахаешься делать автомат, когда тебе придётся решать другие задачи протокола POP3, например, считывать письмо до последовательности \r\n.\r\n. То есть чем протокол "хитрее", как ты выразился, тем больше промежуточных состояний у тебя будет.
Никаких тредов быть не может, потому что один поток не потянет больше десятков клиентов и GUI. И это факт.
Моя реализация тоже пишется и отлаживается один раз. Кроме того, отлаживать её гораздо проще в силу отсутствия дыр в program flow.

Dasar

мы даже делали специальный framework, чтобы асинхронные вещи можно было писать как синхронные, и чтобы преобразование из синхронности в асинхронность делалась автоматически.
кол-во ошибок это здоровски уменьшило, и сильно подняло неубиваемость системы.

kokoc88

Вот, проброс евентов через треды.
А потом люди удивляются - а чтож у меня всё валится и как это отлаживать.
Эвенты и нужны в первую очередь для того, чтобы пробрасывать их через потоки. По крайней мере люди не напишут таких анекдотов:
- Папа, а правда твоя ОС многозадачная?
- Правда.
- А покажи?
- Сейчас, дискетка доформатируется.

kokoc88

class QPop {
 private:
  enum State {
    NONE,
Этот код даже не содержит работы с ошибками. То есть, добавь туда ещё и уведомления вышестоящего класса об ошибках и он разрастётся ещё больше. У меня, как ты видишь, это просто средства языка: throw.
Edit: и ещё все connect'ы между этим классом и вышестоящими или между этим классом и сокетом... В общем, полный финиш.

hashion

во-первых тебе следовало использовать State паттерн.

нашёл к чему прие..ся..
Зачем делать POP3 протокол хитрее? Он ровно такой, каким описан в RFC1939.
Да я в курсе, ты только малую часть его реализовал.
Во-вторых ты затрахаешься делать автомат, когда тебе придётся решать другие задачи протокола POP3, например, считывать письмо до последовательности \r\n.\r\n.
Блин, не смеши.
До сих пор не затрахался.

Никаких тредов быть не может, потому что один поток не потянет больше десятков клиентов и GUI. И это факт.

Такс. А выбирать ту же почту как собрался - последовательно в одном потоке?
Вот тебе плюс - выборка той же почты с разных серверов будет происходить быстрее (асинхронный коннект) и не потребуется десятка тредов.
Кстати есть ещё один минус синхронной реализации - проблема экстренной остановки потока из другого треда.
Этот код даже не содержит работы с ошибками. То есть, добавь туда ещё и уведомления вышестоящего класса об ошибках и он разрастётся ещё больше. У меня, как ты видишь, это просто средства языка: throw.

Легко. Выставляешь код ошибки, бросаешь emit Result (errcode); или просто emit, а errnode спрашиваешь у класса.
Edit: и ещё все connect'ы между этим классом и вышестоящими или между этим классом и сокетом... В общем, полный финиш.
Он там один, а с сокетом - 1-2 коннекта.
В общем я предлагаю тему закрыть, для себя я уже испытал все варианты. Для серверов я выбираю мультиплексирование в нескольких процессах или тредах, для клиентов - просто мультиплексирование в одном потоке.
Я просто советую причину вот этого
поведение программы варьируется от полной работоспособности, до спама дебаг сообщений и access violation.
не искать в QT, а искать в своей архитектуре. Более чем уверен, что при отсутствии тредов жалоб на QT у вас было бы поменьше.

hashion

event driven - чаще дохнет, т.к. в event driven очень сложно отслеживать и data flow, и control flow.
соответственно, довольна частая ошибка, что данные уже грохнули или еще не создали, а обращение к ним уже идет.
В основе большинства протоколов лежит система конечных состояний. И не всегда она выглядит так 1->2->3->4->5. Даже исходя из этого control flow легче отслеживать при асинхронном варианте.

Dasar

И не всегда она выглядит так 1->2->3->4->5. Даже исходя из этого control flow легче отслеживать при асинхронном варианте.
приведи пример хоть одного такого протокола

hashion

xmpp
ftp
да даже pop - ветвление начинается, когда решается вопрос о способе авторизации. Но это мелко.

Dasar

xmpp
ftp
xmpp - хз, что это.
в ftp - все плоско, все упихивается в if-ы и for-ы
да даже pop - ветвление начинается, когда решается вопрос о способе авторизации. Но это мелко.
сихронный if уже отменили?
ps
я думал, ты знаешь, что когда идет спор асинк <-> синк (state или plain то считается, что протокол "плохой"(плохо ложится на синхронный вариант когда его состояния - не ложатся на скобочную запись.

kokoc88

нашёл к чему прие..ся..
Это серьёзное замечание, учитывая какого размера у тебя получится ряд if-else, который вообще надо было сделать switch-ем и в котором у тебя уже есть ошибка.
Зачем делать POP3 протокол хитрее? Он ровно такой, каким описан в RFC1939.
--------------------------------------------------------------------------------
Да я в курсе, ты только малую часть его реализовал.
Я реализовал его полностью. Класс размером 265 строк реализации и 80 строк заголовка. Боюсь даже предположить, какого размера он получится при event driven подходе. А если мы ещё и сделаем его не на основе конкретного сокета, а на основе абстрактного текстового потока, что в общем-то правильно, то твой код распухнет, как женатый поп.
Во-вторых ты затрахаешься делать автомат, когда тебе придётся решать другие задачи протокола POP3, например, считывать письмо до последовательности \r\n.\r\n.
--------------------------------------------------------------------------------
Блин, не смеши.
До сих пор не затрахался.
Ну что сказать, если ты просто не привык делать вещи так, чтобы их было удобно писать и отлаживать, то это просто подтверждает мои слова: Qt программисты очень ограничены и любое ООП решение сводят к ещё одному сигналу-слоту. Хотя мне было бы очень интересно посмотреть на полную реализацию POP3 на event driven, пусть даже без парсинга писем по RFC2822. Особенно интересным был бы момент, в котором кроме енума состояний пришлось бы создать буфер для временного хранения байтов тела письма.
Вот тебе плюс - выборка той же почты с разных серверов будет происходить быстрее (асинхронный коннект) и не потребуется десятка тредов.
С чего это ты взял, что выборка почты у тебя будет быстрее? У меня будет тред пул достаточного размера, чтобы во-первых, полностью загрузить канал; и во-вторых, порвать твою реализацию на Core Duo/Quadro.
Кстати есть ещё один минус синхронной реализации - проблема экстренной остановки потока из другого треда.
Эта проблема есть только у объектов Qt. Нормальная реализация синхронных запросов может быть прервана из любого потока.
Этот код даже не содержит работы с ошибками. То есть, добавь туда ещё и уведомления вышестоящего класса об ошибках и он разрастётся ещё больше. У меня, как ты видишь, это просто средства языка: throw.
--------------------------------------------------------------------------------
Легко. Выставляешь код ошибки, бросаешь emit Result (errcode); или просто emit, а errnode спрашиваешь у класса.

Ага, то есть твой код ещё больше распухает. Кстати, сигнал ошибки тебе придётся запихать как в класс протокола, так и в класс транспорта для этого протокола.
Я просто советую причину вот этого
В ответ на:
--------------------------------------------------------------------------------
поведение программы варьируется от полной работоспособности, до спама дебаг сообщений и access violation.
--------------------------------------------------------------------------------
не искать в QT, а искать в своей архитектуре. Более чем уверен, что при отсутствии тредов жалоб на QT у вас было бы поменьше.

Я просто советую тебе не советовать никому ничего по поводу ООП архитектуры, если ты не признаёшь GoF или не способен сразу же разглядеть, к каким проблемам приведёт enum вместо state pattern в случае с протоколом POP3. А при отсутствии тредов клиенты начнут жаловаться на отсутствие responsibility в нашем GUI.

kokoc88

xmpp
Представь себе, я реализовал этот протокол синхронно. И вообще я не понимаю, почему синхронная реализация мешает писать протоколы с состояниями. Кроме того, изначальный спор был о том, что Qt заставляет вещи, которые просто делаются без состояний, делать с состояниями. Что является минусом и poor design.

kokoc88

Даже исходя из этого control flow легче отслеживать при асинхронном варианте.
Это вообще фраза, которая говорит о незнании теории. Чтобы спорить, что лучше: batch vs event, надо хотя бы знать определения и плюсы-минусы обоих подходов.
In computer programming, event-driven programming or event-based programming is a programming paradigm in which the flow of the program is determined by sensor outputs or user actions (mouse clicks, key presses) or messages from other programs or threads.

Из какой части этого определения ты сделал вывод о том, что control flow легче отслеживать в event driven?

hashion

А при отсутствии тредов клиенты начнут жаловаться на отсутствие responsibility в нашем GUI.
В вашем - может быть, на наши однопотоковые GUI никто никогда не жаловался.
Qt программисты очень ограничены [..]
советую тебе не советовать никому ничего [..]
Эта проблема есть только у объектов Qt [..]
Уважаемый, идите ка вы ищете баги в своём коде с таким отношением.
Вы всё правильно делаете - не на кого валить - валите на QT.

kokoc88

В вашем - может быть, на наши однопотоковые GUI никто никогда не жаловался.
Просто в силу того, что они не выполняют никаких сложных действий.
Уважаемый, идите ка вы ищете баги в своём коде с таким отношением.
Вы всё правильно делаете - не на кого валить - валите на QT.

Уважаемый, идите ка вы вообще с таким отношением. Написал псевдокод в 2.5 раза больше по строкам, с ошибкой в логике, с ошибкой в проектировании, да ещё и продолжаешь утверждать что-то там про event driven, даже не зная определения того, что это такое. Слив защитан.

hashion

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

kokoc88

Это уже превращается в идиотизм.
Нет, в идиотизм превращается всё, что сказано до этого.
Во-первых, ты сказал, что отслеживать program flow проще в event driven подходе.
Во-вторых, ты написал псевдокод в два раза длинее и с логическими ошибками. Надеюсь, что ты понял, что был не прав. Но почему-то ты продолжил мяться и писать какую-то незначимую ерунду про наличие или отсутствие потоков в программе.
В-третьих, все твои аргументы были поностью покрыты: твоя программа тяжелее дебажится; не имеет ничего такого, что было бы сложнее делать при batch или mixed подходе; работает медленнее; содержит потенциальные проблемы, связанные с data flow; и содержит потенциальные проблемы, связанные с временем отклика GUI части.

kokoc88

Для интересующихся, если наш знаток Ash не найдёт правильных аргументов, то через некоторое время я сам напишу, когда event driven лучше.

hashion

То что ты пишешь - это есть недопонимание концепций построения и реализаций протоколов вобще и сетевого взаимодействия в частности. В чём у тебя причина - я не знаю. Результат на лицо - гневные выпады в отношении Qt (и в мой адрес, но это пофиг хотя эта либа тут и близко не причём.
Что ты там выдумываешь, какой линейкой измеряешь псевдокод (вобще бред) меня уже волнует мало. Я уже понял - доказать что-то тебе нереально и делать этого не собираюсь.
Если кто-то хочет подискутировать на эту тему - велкам, лучше в приват или в аську, но только при наличии адекватного поведения.

kokoc88

То что ты пишешь - это есть недопонимание концепций построения и реализаций протоколов вобще и сетевого взаимодействия в частности. В чём у тебя причина - я не знаю. Результат на лицо - гневные выпады в отношении Qt (и в мой адрес, но это пофиг хотя эта либа тут и близко не причём.
Аргументы в студию. Все мои наезды более-менее обоснованы и очевидны по сообщениям в этой ветке. И как я вижу, кроме каких-то абстрактных ответов, крыть тебе не чем. Предлагаю в качестве аргументации реализацию протокола POP3 вплоть до полной загрузки байтов тела сообщения. Для простоты предлагаю взять только команды TOP, LIST, UIDL, PASS, USER, RETR.
Что ты там выдумываешь, какой линейкой измеряешь псевдокод (вобще бред) меня уже волнует мало. Я уже понял - доказать что-то тебе нереально и делать этого не собираюсь.
Доказать мне что-то можно только аргументами, которые не являются противоречивыми. Ты же не споришь, что твоя фраза про control flow была неправильной. И вообще всё время уходишь от темы. Сначала у меня, оказывается, баги в программе. Да с чего ты это вообще взял? Перечисление недостатков Qt вовсе не означает, что у меня что-то не работает. Это лишь означает, что я использую Qt правильно, чтобы избежать этих проблем, и что это не удобно. Потом оказывается, что я что-то не умею делать. Как ты связал это и перечисление очевидных недостатков Qt я вообще слабо понимаю. Ближе к теме: Qt неудобно во многих случаях, а программисты на Qt решают все вопросы очередным слотом-сигналом, хотя в этой ветке уже показано, во что превращается такой подход. До сих пор не согласен - приводи агрументы, пиши код, а не беспочвенные домыслы.

hashion

поведение программы варьируется от полной работоспособности, до спама дебаг сообщений и access violation.
Сначала у меня, оказывается, баги в программе. Да с чего ты это вообще взял?
:D
Перечисление недостатков Qt вовсе не означает, что у меня что-то не работает. Это лишь означает, что я использую Qt правильно [...]
Все мои наезды более-менее обоснованы и очевидны
Я хренею от самонадеянности.
Всё, ты Бог, пиши свои программы как хочешь, мне пофигу.

kokoc88

Я хренею от самонадеянности.
Всё, ты Бог, пиши свои программы как хочешь, мне пофигу.
Аргументов нет. Код для оценки ты писать не хочешь. Слив засчитан.

hashion

Код для оценки ты писать не хочешь.
Денег дашь?

kokoc88

Денег дашь?
Зачем деньги? Очевидно, ты не можешь признать свою неправоту. Я предлагаю перевести теоретический спор в практическую плоскость. Я тоже напишу код, и готов его запостить первым. Тем более, мне не жалко 60-80 минут своего времени, чтобы поставить на место такого выскочку.

Ivan8209

> Вот тебе плюс - выборка той же почты с разных серверов будет
> происходить быстрее (асинхронный коннект) и не потребуется
> десятка тредов.
Тебе сюда.
---
...Я работаю антинаучным аферистом...
Оставить комментарий
Имя или ник:
Комментарий: