Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Disruptor: рвем связь между бизнес-логикой и сетью


Автор: drug007 28.11.2011, 12:42
Есть сетевое приложение, где нужно развязать сетевую часть и бизнес-логику через общий буфер, в который сетевая часть пишет и берет своё, а бизнес-логика своё. Ходят слухи, что для этого используют паттерн disruptor.  Мне он тоже кажется подходящей кандидатурой, но хочется уточнить некоторые моменты.
http://habrahabr.ru/blogs/hi/130113/ буффер дисраптора описан состоящим из слотов или entry. Дальнейшее изучение (пока по диагонали правда) явовской оригинальной версии дисраптора показало, что в качестве слота используется либо указатель, либо простая структура (та самая entry), имеющая члены-указатели на данные и/или различные флаги. Т.о. если я использую boost::asio, в startRead() я должен выделить необходимое количество памяти, передать его в async_read_X, затем в handleRead() я должен запросить у disruptor'а свободный слот и присвоить указатель на ранее выделенный буфер одному из полей этого слота и затем закоммиттить полученный слот. Далее опять выделение памяти и по новой?. 
Т.е. как я понял, я не могу:
а) использовать в качестве слота char
б) в startRead() попросить disruptor выделить из своего внутреннего буфера свободное место (как boost::asio::buffer(), for example), чтобы я мог его передать в async_read_X без выделения памяти каждый раз?
в) в handleRead просто закомиттить запрошеный слот (если произойдет сбой, то испорченный слот можно закомиттить испорченным и потребители его просто проигнорируют)? 

Просвятите, пожалуйста, насчет такой возможности.

Автор: boostcoder 28.11.2011, 14:48
мне показалось что ты изучаешь жава реализацию дисраптора. если да, то плюсовая реализация тут: http://code.google.com/p/disruptor-cpp/

Цитата(drug007 @  28.11.2011,  12:42 Найти цитируемый пост)
если я использую boost::asio, в startRead() я должен выделить необходимое количество памяти, передать его в async_read_X, затем в handleRead() я должен запросить у disruptor'а свободный слот и присвоить указатель на ранее выделенный буфер одному из полей этого слота и затем закоммиттить полученный слот. Далее опять выделение памяти и по новой?

не уверен что правильно понял..
твои Entry ты реализуешь таким образом, чтоб они содержали буфера как свои члены. у Producer нужно попросить следующий Entry. у полученного Entry получаешь указатель на буфер, который и используешь далее. (буфера, можно создавать в каждом Entry всего однажды, для уменьшения затрат/уменьшения фрагментации. далее же, проверяешь размер буфера, и ,если он меньше необходимого - перевыделяешь память. или же, при использовании пула буферов, просишь пул вернуть тебе указатель на подходящий буфер. если такого нет, пул сам создаст его и вернет тебе).

Добавлено @ 14:55
не уверен что понял вопрос..по этому и ответ получился какой-то сумбурный =)

Автор: drug007 29.11.2011, 05:31
Явовскую реализацию я смотрел, т.к. плюсовая ссылается на ее документацию. Но за ссылку все равно спасибо.
Ответ как раз то, что нужно. =) 
Просто я в самом начале попытался реализовать свой простой disruptor как массив байтов (circular_buffer<char>) - вырожденный вариант Entry, вроде как память экономить - и в итоге такая хня получилась возникли сложности в управлении памятью - нужны уже непростые алгоритмы, либо Entry делать как массив байтов, но тогда возможен перерасход памяти. Деваться некуда стало, пришлось подробнее читать про оригинал, ряд вопрос снялся. Но  решил еще уточнить у знающих людей. Уже задав вопрос здесь пришел к выводу, что оптимально будет сделать  в Entry указатели, а память выделять из предварительно выделенного глобального буфера - собственно о том же и ответ.
Т.о. правильнее будет просто прописать размер типового буфера в Entry как настройку приложения и переложить проблему баланса между быстродействием и расходом памяти с плеч программиста на плечи администратора приложения - пусть он сам подбирает необходимый ему размер буфера?
Пойду дальше курить disruptor.

Автор: boostcoder 29.11.2011, 13:14
Цитата(drug007 @  29.11.2011,  05:31 Найти цитируемый пост)
Т.о. правильнее будет просто прописать размер типового буфера в Entry как настройку приложения и переложить проблему баланса между быстродействием и расходом памяти с плеч программиста на плечи администратора приложения - пусть он сам подбирает необходимый ему размер буфера?

да. ну можно таки еще и про пул буферов/объектов подумать. что-то типа http://www.boost.org/doc/libs/1_48_0/libs/pool/index.html.

Автор: drug007 30.11.2011, 10:07
Немного оффтоп. smile
Все-таки есть что-то дьявольское в бусте - мое знакомство с ним началось с асио, ибо как-то уж писать на сокетах вообще расхотелось. Привлекательность буста резко возрасла, когда мне надо было связаться с мобильным телефоном через компорт и я не смог быстро этого сделать (под виндой через ее родной API) даже используя уже имеющийся рабочий код из другого приложения. И я не мудрствуя лукаво сделал это действительно быстро буквально в пару-тройку строк с помощью буста. Но с другой стороны углубляясь в буст я все больше понимал свою безграмотность в этом мире и вспоминал слова дедушки Владимира Ильича (как же он был прав!). И теперь с одной стороны я уже длительное время не могу приступить к собственно решению задачи потому что занят изучением буста - с другой стороны очень хочется построить проект так, чтобы он нуждался только в развитии, но не в переделке. Поэтому рассчитываю на некоторую фундаментальность буста (исхожу из того, что в его основе больше лежит все-таки математический подход, а не код в стиле "поток сознания") и готов тратить время на его изучение, ожидая, что смогу опираться на него. А дьявольское - это то, что буст меня фактически затягивает в свои сети smile Несмотря на то, что я уже испытываю сложности с его освоением (он сверху очень простой, а внутри чем дальше, тем сложнее), но и отказаться от него не могу - прямо секта какая-то! smile

Теперь по теме - благодарю за ссылку, уже изучаю.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)