Форум программистов, компьютерный форум CyberForum.ru

Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно - C++

Восстановить пароль Регистрация
 
 
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
22.11.2016, 13:37     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #1
Привет!

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

Итак - есть RPC канал, который реагирует на события AMQP сервера (используется событийная модель). Из RPC канала нужно асинхронно ответить на сообщение, для этого AMQP нужны данные, о которых знает только AMQP. Т.е. эти данные нужно прокинуть из AMQP в RPC, и RPC потом должен эти данные вернуть. Чтоб все было кошерно нужно:
1. Чтобы RPC не знал об AMQP (транспорт должен быть заменяемым)
2. Не нужно заставлять пользователя (т.е. RPC) что-то куда-то прокидывать

Чтоб было понятней (очень упращенный вариант)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// AMQP
void AmqpServer::mainLoop()
{
    // что-то делаем, в итоге получаем сообщение
   // при этом есть некий ID, который нужно знать при отправке ответа
   
    _messageHandler->onMessageReceived(message/*, также нужно как-то прокинуть упомянутый ID*/);
}
 
void AmqpServer::sendResponse (std::string response, /* и еще нужно знать упомянутый выше ID*/)
{
    // отправляем сообщение, используя ID
}
 
// RPC
void RpcChannel::onMessageReceived (std::string message/*, нужен еще ID*/)
{
    // обработали сообщение, сформировали ответ
 
    _responseHandler->sendResponse(response/*, плюс нужно вернуть ID*/);
}
Вариант с кешированием IDшников на стороне сервера сразу отметаем по ряду причин. Есть предложения?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.11.2016, 13:37     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно
Посмотрите здесь:

C++ Удалить самый высокий лист в дереве
Можно ли переделать проект из более поздней Visual Studio в более раннюю? Visual C++
C++ Как вернуть обратно к switch
C++ Задача Robot. Найти количество единичных квадратов, на которых робот побывал более одного раза
C++ Найти слова, которые состоят из 3х и более букв и имеют более 2х гласных
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
 Аватар для vxg
2659 / 1670 / 156
Регистрация: 13.01.2012
Сообщений: 6,215
23.11.2016, 13:44     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #21
Kastaneda, то есть:
-пришло сообщение из космоса на 1-й уровень (мы добавили к сообщению какие-то свои пометки)
-сообщение пересылается с 1-го на 2-й уровень
-ответ посылается со 2-го на 1-й уровень
-ответ уходит с 1-го уровня в космос (мы добавили к ответу какие-то свои пометки которые были добавлены к сообщению когда оно пришло)
так?
-----
ну тогда все нормально - взять и пихать в экстру. 2-й уровень даже не будет знать что там - просто перекинет экстру в ответ. а 1-й уровень сам должен знать как ему и что использовать
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6165 / 2894 / 282
Регистрация: 04.12.2011
Сообщений: 7,694
Записей в блоге: 3
23.11.2016, 13:46     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #22
Цитата Сообщение от IGPIGP Посмотреть сообщение
На предмет есть ли там место для "комментария" в виде id.
В тех данных которые возвращаются без изменения (если есть такие). Это было бы идеально. Иначе придётся заставить клиента передать дополнительную инфу.

Добавлено через 1 минуту
Цитата Сообщение от vxg Посмотреть сообщение
2-й уровень даже не будет знать что там - просто перекинет экстру в ответ.
Кроме того, что ему придётся знать, что экстру надо перекинуть в ответ.
vxg
Модератор
 Аватар для vxg
2659 / 1670 / 156
Регистрация: 13.01.2012
Сообщений: 6,215
23.11.2016, 13:53     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #23
Цитата Сообщение от IGPIGP Посмотреть сообщение
Кроме того, что ему придётся знать, что экстру надо перекинуть в ответ.
мы слишком мало знаем про архитектуру что бы делать выводы о том что ему будет сложно или даже невозможно. для меня очевидно что если эти данные мы не помещаем ни в кэш ни в само сообщение, то их вообще нельзя будет получить разве что запросить повторно из космоса
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6165 / 2894 / 282
Регистрация: 04.12.2011
Сообщений: 7,694
Записей в блоге: 3
23.11.2016, 13:56     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #24
Цитата Сообщение от vxg Посмотреть сообщение
ришло сообщение из космоса
Я увидел только 1 и 2 уровни. Первому нужно знать что-то о происшедшем на момент отправки (о времени отправки например) на 2. 2 должен вернуть первому то что должен (то о чём он знает) + вот эту дополнительную информацию.
И заставить его вернуть её может быть самостоятельной задачкой.
Или я усложняю, Kastaneda?

Добавлено через 58 секунд
Цитата Сообщение от vxg Посмотреть сообщение
мы слишком мало знаем про архитектуру что бы делать выводы о том что ему будет сложно или даже невозможно.
Это верно. Гадаем.
Но фраза о том что "2 не должен знать" звучит довольно жестко. Как же он добавит к тому что "знает". Ему что, метод расшифровки сообщения и подготовки ответа сереализовать и в сообщение положить вначале?
vxg
Модератор
 Аватар для vxg
2659 / 1670 / 156
Регистрация: 13.01.2012
Сообщений: 6,215
23.11.2016, 14:06     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #25
IGPIGP, если фраза "2 не должен знать" моя то я имел ввиду что 2-й уровень просто будет знать что нужно прицепить к ответу экстру взятую из запроса. содержимое в этом случае знать не нужно. нужно знать только размер. ну или в более общем случае - нужно только скопировать ссылку на экстру или вызвать метод clone
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6165 / 2894 / 282
Регистрация: 04.12.2011
Сообщений: 7,694
Записей в блоге: 3
23.11.2016, 14:23     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #26
Цитата Сообщение от vxg Посмотреть сообщение
если фраза "2 не должен знать" моя то я имел ввиду что 2-й уровень просто будет знать что нужно прицепить к ответу экстру взятую из запроса.
нет эта фраза есть в постановке:
Цитата Сообщение от Kastaneda Посмотреть сообщение
для этого AMQP нужны данные, о которых знает только AMQP.

Тут возможно, надо анализировать активное содержимое сообщения, если оно есть. (полубред в отсутствии конкретики).
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
24.11.2016, 07:34  [ТС]     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #27
Цитата Сообщение от vxg Посмотреть сообщение
Kastaneda, то есть:
-пришло сообщение из космоса на 1-й уровень (мы добавили к сообщению какие-то свои пометки)
-сообщение пересылается с 1-го на 2-й уровень
-ответ посылается со 2-го на 1-й уровень
-ответ уходит с 1-го уровня в космос (мы добавили к ответу какие-то свои пометки которые были добавлены к сообщению когда оно пришло)
так?
Sorry, если не понятно объяснил. Реально происходит следующее:
1. На AMQP сервер приходит сообщение. Сообщение содержит в том числе поля replyTo и correlationID, которые нужны для формирования ответа на это сообщение.
2. Сообщение нужно отдать на верх (уровень RPC).
3. RPC должен его обработать и ответить. На уровне RPC ответ - это просто string
4/ AMQP должен упаковать этот ответ (string) в свой формат сообщения. Для этого ему нужны replyTo и correlationID,

Цитата Сообщение от IGPIGP Посмотреть сообщение
Кроме того, что ему придётся знать, что экстру надо перекинуть в ответ.
Да, что не есть хорошо. Плюс зачем ему (2-му уровню) приходят какие-то непонятные данные, которые ему даже не нужны.

Менять по идее можно все, что угодно. Чтоб было понятно, у нас тут были предолжены например такие варианты:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// AMQP
void AmqpServer::mainLoop()
{
    // что-то делаем, в итоге получаем сообщение
   // при этом есть некий ID, который нужно знать при отправке ответа
   
   auto sendResponse = std::bind(&AmqpServer::sendResponse, this, replyTo, correlationId, _1);
    _messageHandler->onMessageReceived(message, sendResponse);
}
 
void AmqpServer::sendResponse (std::string replyTo, std::string correlationId, std::string response)
{
    // отправляем сообщение
}
 
// RPC
void RpcChannel::onMessageReceived (std::string message, std::function<void(std::string) sendResponse)
{
    // обработали сообщение, сформировали ответ
    sendResponse(response);
}
Либо тоже самое, но через паттерн "Команда". Либо создать класс Request, который имеет метод createResponse(), этот Request передать в RPC, а там дернуть createResponse(), и в этом response будут невидимые для RPC replyTo и correlationID. Этот response отдаем в AMQP и он уже может прочитать нужные ему поля (как вариант через френдов можно разрулить доступ к полям).

Это более менее адекватные предложения (были совсем не адекватные), но мне лично ни один из этих подходов не нравится. Интуитивно чувствуется какая-то костыльность, есть ощущение, что можно сделать лучше/проще, но решение в голову не лезет.
vxg
Модератор
 Аватар для vxg
2659 / 1670 / 156
Регистрация: 13.01.2012
Сообщений: 6,215
24.11.2016, 10:09     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #28
Цитата Сообщение от Kastaneda Посмотреть сообщение
есть ощущение, что можно сделать лучше/проще, но решение в голову не лезет
-написать базовый класс "сообщение"
-этот класс имеет виртуальный метод "добавить данные" принимающий и сохраняющий в объекте некие данные (replyTo и correlationID в случае AMQP) и "сформировать ответ" принимающий message от RPC и возвращающий то что должен послать AMQP (или иная сущность)
-написать производный класс "сообщение AMQP" в котором реализовать эти методы
-во время приема сообщения "добавлять данные"
-перед отправкой "формировать ответ"
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6165 / 2894 / 282
Регистрация: 04.12.2011
Сообщений: 7,694
Записей в блоге: 3
24.11.2016, 11:00     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #29
Цитата Сообщение от Kastaneda Посмотреть сообщение
Либо создать класс Request, который имеет метод createResponse(), этот Request передать в RPC
Цитата Сообщение от это легко
Коля: -Как мне, на уроке, передать записку Леночке, но так, чтобы не Марья Петровна ни Леночка этого не заметили.
Вася: -Видишь, в последнем ряду пустую парту? Положи в неё записку, а потом двигай её в первый ряд, - к парте Леночки.
Kastaneda, я всё ещё не понимаю механики. Для меня важно как RPC формирует и отправляет ответ. Ведь это он должен "не зная отправить"?
Поэтому, говоря мутно и заклинательно:
Если в сообщении AMPQ можно передать метод который будет автоматически запущен пока текст сообщения еще не потерян, то можно этот метод использовать либо путём расширения его кода, либо путём приаттачивания делегата к программному обеспечению RPC. Но избыточной информации в виде как активной части сообщения так и прилагаемых данных не избежать. В этом случае "RPC не знает" будет означать, "не должен знать до получения". Даже при использовании делегата, он таки не знает, хоть и может проверить цепочку актуальных делегатов. Потому что новый может её изменить.
Но при отправке он будет знать и делать.
Иначе, нужен прокси хардвер объект, который будет между. То есть будет включать в себя RPC. Но это та же парта, но тяжелая.
Простите, если не врубаюсь.
vxg
24.11.2016, 11:04
  #30

Не по теме:

IGPIGP, магнитный монополь...

IGPIGP
24.11.2016, 11:10
  #31

Не по теме:

IGPIGP, магнитный монополь...
Пол магнита, - эка невидаль. У барона вон, пол коня было! Правда увековечили целиком, а струю приаттачили читая ТЗ под чутким руководством бургомистра. Но вышло не менее весело и поучительно.

Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
24.11.2016, 12:17  [ТС]     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #32
Цитата Сообщение от vxg Посмотреть сообщение
-написать базовый класс "сообщение"
-этот класс имеет виртуальный метод "добавить данные" принимающий и сохраняющий в объекте некие данные (replyTo и correlationID в случае AMQP) и "сформировать ответ" принимающий message от RPC и возвращающий то что должен послать AMQP (или иная сущность)
-написать производный класс "сообщение AMQP" в котором реализовать эти методы
-во время приема сообщения "добавлять данные"
-перед отправкой "формировать ответ"
Была такая идея, но тогда в AMQP сообщение будет передано по интерфейсу (базовому классу) и внутри AMQP нужно будет делать down cast, что тоже хочется избежать, т.к. теоретически cast может быть невалидным.

Цитата Сообщение от IGPIGP Посмотреть сообщение
я всё ещё не понимаю механики. Для меня важно как RPC формирует и отправляет ответ.
RPC выполняет команды, которые приходят по сети (через AMQP). Допустим пришла команда "дай мне серверное время", AMQP отбрасывает оттуда все, что касается протокола AMQP и отдает в RPC строку "дай мне серверное время". RPC понимает эту строку и возвращает строку "14:53". Т.е. на уровне RPC есть только строки "команда" и "ответ".

Цитата Сообщение от IGPIGP Посмотреть сообщение
нужен прокси хардвер объект
Кстати выглядит не плохо, ща обдумаю.

Добавлено через 8 минут
Цитата Сообщение от Kastaneda Посмотреть сообщение
Кстати выглядит не плохо, ща обдумаю.
Не, теретически верхний уровень (RPC) работает асинхронно, поэтому данные внутри прокси могут не соответствовать тому запросу, на который мы отвечаем. Тогда нужно как-то хранить данные, и тогда нужно как-то давать понять прокси на какой запрос мы отвечаем. В этом случае профит от прокси теряется. Было все синхронно было бы проще.
vxg
Модератор
 Аватар для vxg
2659 / 1670 / 156
Регистрация: 13.01.2012
Сообщений: 6,215
24.11.2016, 12:27     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #33
Цитата Сообщение от Kastaneda Посмотреть сообщение
т.к. теоретически cast может быть невалидным
с чего бы это вдруг? вы реализацию на лету можете поменять между приемом и ответом одного сообщения?

Добавлено через 2 минуты
...даже если так базовый класс может поддерживать единую для всех реализаций функцию "узнай какого типа сообщение внутри меня" - если при ответе мы видим что сообщение сформировано другой реализацией очевидно был горячий рестарт и нам не остается ничего кроме как отбросить такое сообщение так как мы не знаем как с ним работать
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6165 / 2894 / 282
Регистрация: 04.12.2011
Сообщений: 7,694
Записей в блоге: 3
24.11.2016, 13:12     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #34
Цитата Сообщение от Kastaneda Посмотреть сообщение
Тогда нужно как-то хранить данные, и тогда нужно как-то давать понять прокси на какой запрос мы отвечаем.
Хранить данные обязательно. И на AMQP же хранится id, если только id не является "командной" информацией. Давать понять придётся так же как Вы собираетесь делать сейчас, но возможно более явно, что просто проще.
Цитата Сообщение от Kastaneda Посмотреть сообщение
В этом случае профит от прокси теряется.
Профит от тяжелой парты прокси компонента только в том, что есть возможность сохранить программное обеспечение RPC совершенно нетронутым. То есть он действительно сможет "не знать". Но у такого неведения есть немалая цена. Это правда.
Это не потому, что фраза "знание умножает скорбь" неправа. Это потому что и незнание её тоже, мягко говоря, не уменьшает. Только мы с Вами можем её уменьшить. Например, тиснуть вот такой смайлик:
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.11.2016, 17:53     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно
Еще ссылки по теме:

Детали реализации конструктора класса C++
C++ Из функции вернуть более одного значения

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
HighPredator
 Аватар для HighPredator
5342 / 1725 / 320
Регистрация: 10.12.2010
Сообщений: 5,108
Записей в блоге: 3
28.11.2016, 17:53     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно #35
Kastaneda, очень долго читал, но так до конца и не понял. Вы можете словесно-схематично+абстрактно (без аббривеатур, а на уровне класс1/черный_ящик1) показать желаемую схему работы в контексте обмена данными?
Yandex
Объявления
28.11.2016, 17:53     Задача дизайна - прокинуть детали низкоуровневой реализации на более высокий уровень и вернуть обратно
Ответ Создать тему
Опции темы

Текущее время: 22:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru