Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,135
Записей в блоге: 2
1

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

22.11.2016, 13:37. Показов 1359. Ответов 34
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет!

Задача возникла на работе. Мозговым штурмом было предложено 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шников на стороне сервера сразу отметаем по ряду причин. Есть предложения?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.11.2016, 13:37
Ответы с готовыми решениями:

Необходим более высокий уровень знаний!
Ребят, тут такое дело, мне через год поступать, экзамены сдавать, аттестации и т. д. Проблема в...

Ежедекадно в течение июня измерялся уровень воды в десяти речках. Определить подекадно: в каких речках наблюдался самый высокий уровень
Ежедекадно в течение июня измерялся уровень воды в десяти речках. Определить подекадно: в каких...

Высокий уровень
Используя пять вариантов наборов карт 1)«6», «7», «8» 2)«7», «8», «9» 3) «6», «9», «10» 4)«6»,...

Высокий уровень шума
Здравствуйте, являюсь владельцем данной модели...

34
Модератор
3388 / 2160 / 352
Регистрация: 13.01.2012
Сообщений: 8,379
23.11.2016, 13:44 21
Author24 — интернет-сервис помощи студентам
Kastaneda, то есть:
-пришло сообщение из космоса на 1-й уровень (мы добавили к сообщению какие-то свои пометки)
-сообщение пересылается с 1-го на 2-й уровень
-ответ посылается со 2-го на 1-й уровень
-ответ уходит с 1-го уровня в космос (мы добавили к ответу какие-то свои пометки которые были добавлены к сообщению когда оно пришло)
так?
-----
ну тогда все нормально - взять и пихать в экстру. 2-й уровень даже не будет знать что там - просто перекинет экстру в ответ. а 1-й уровень сам должен знать как ему и что использовать
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
23.11.2016, 13:46 22
Цитата Сообщение от IGPIGP Посмотреть сообщение
На предмет есть ли там место для "комментария" в виде id.
В тех данных которые возвращаются без изменения (если есть такие). Это было бы идеально. Иначе придётся заставить клиента передать дополнительную инфу.

Добавлено через 1 минуту
Цитата Сообщение от vxg Посмотреть сообщение
2-й уровень даже не будет знать что там - просто перекинет экстру в ответ.
Кроме того, что ему придётся знать, что экстру надо перекинуть в ответ.
0
Модератор
3388 / 2160 / 352
Регистрация: 13.01.2012
Сообщений: 8,379
23.11.2016, 13:53 23
Цитата Сообщение от IGPIGP Посмотреть сообщение
Кроме того, что ему придётся знать, что экстру надо перекинуть в ответ.
мы слишком мало знаем про архитектуру что бы делать выводы о том что ему будет сложно или даже невозможно. для меня очевидно что если эти данные мы не помещаем ни в кэш ни в само сообщение, то их вообще нельзя будет получить разве что запросить повторно из космоса
1
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
23.11.2016, 13:56 24
Цитата Сообщение от vxg Посмотреть сообщение
ришло сообщение из космоса
Я увидел только 1 и 2 уровни. Первому нужно знать что-то о происшедшем на момент отправки (о времени отправки например) на 2. 2 должен вернуть первому то что должен (то о чём он знает) + вот эту дополнительную информацию.
И заставить его вернуть её может быть самостоятельной задачкой.
Или я усложняю, Kastaneda?

Добавлено через 58 секунд
Цитата Сообщение от vxg Посмотреть сообщение
мы слишком мало знаем про архитектуру что бы делать выводы о том что ему будет сложно или даже невозможно.
Это верно. Гадаем.
Но фраза о том что "2 не должен знать" звучит довольно жестко. Как же он добавит к тому что "знает". Ему что, метод расшифровки сообщения и подготовки ответа сереализовать и в сообщение положить вначале?
0
Модератор
3388 / 2160 / 352
Регистрация: 13.01.2012
Сообщений: 8,379
23.11.2016, 14:06 25
IGPIGP, если фраза "2 не должен знать" моя то я имел ввиду что 2-й уровень просто будет знать что нужно прицепить к ответу экстру взятую из запроса. содержимое в этом случае знать не нужно. нужно знать только размер. ну или в более общем случае - нужно только скопировать ссылку на экстру или вызвать метод clone
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
23.11.2016, 14:23 26
Цитата Сообщение от vxg Посмотреть сообщение
если фраза "2 не должен знать" моя то я имел ввиду что 2-й уровень просто будет знать что нужно прицепить к ответу экстру взятую из запроса.
нет эта фраза есть в постановке:
Цитата Сообщение от Kastaneda Посмотреть сообщение
для этого AMQP нужны данные, о которых знает только AMQP.

Тут возможно, надо анализировать активное содержимое сообщения, если оно есть. (полубред в отсутствии конкретики).
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,135
Записей в блоге: 2
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 и он уже может прочитать нужные ему поля (как вариант через френдов можно разрулить доступ к полям).

Это более менее адекватные предложения (были совсем не адекватные), но мне лично ни один из этих подходов не нравится. Интуитивно чувствуется какая-то костыльность, есть ощущение, что можно сделать лучше/проще, но решение в голову не лезет.
0
Модератор
3388 / 2160 / 352
Регистрация: 13.01.2012
Сообщений: 8,379
24.11.2016, 10:09 28
Цитата Сообщение от Kastaneda Посмотреть сообщение
есть ощущение, что можно сделать лучше/проще, но решение в голову не лезет
-написать базовый класс "сообщение"
-этот класс имеет виртуальный метод "добавить данные" принимающий и сохраняющий в объекте некие данные (replyTo и correlationID в случае AMQP) и "сформировать ответ" принимающий message от RPC и возвращающий то что должен послать AMQP (или иная сущность)
-написать производный класс "сообщение AMQP" в котором реализовать эти методы
-во время приема сообщения "добавлять данные"
-перед отправкой "формировать ответ"
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
24.11.2016, 11:00 29
Цитата Сообщение от Kastaneda Посмотреть сообщение
Либо создать класс Request, который имеет метод createResponse(), этот Request передать в RPC
Цитата Сообщение от это легко
Коля: -Как мне, на уроке, передать записку Леночке, но так, чтобы не Марья Петровна ни Леночка этого не заметили.
Вася: -Видишь, в последнем ряду пустую парту? Положи в неё записку, а потом двигай её в первый ряд, - к парте Леночки.
Kastaneda, я всё ещё не понимаю механики. Для меня важно как RPC формирует и отправляет ответ. Ведь это он должен "не зная отправить"?
Поэтому, говоря мутно и заклинательно:
Если в сообщении AMPQ можно передать метод который будет автоматически запущен пока текст сообщения еще не потерян, то можно этот метод использовать либо путём расширения его кода, либо путём приаттачивания делегата к программному обеспечению RPC. Но избыточной информации в виде как активной части сообщения так и прилагаемых данных не избежать. В этом случае "RPC не знает" будет означать, "не должен знать до получения". Даже при использовании делегата, он таки не знает, хоть и может проверить цепочку актуальных делегатов. Потому что новый может её изменить.
Но при отправке он будет знать и делать.
Иначе, нужен прокси хардвер объект, который будет между. То есть будет включать в себя RPC. Но это та же парта, но тяжелая.
Простите, если не врубаюсь.
2
vxg
24.11.2016, 11:04
  #30

Не по теме:

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

0
IGPIGP
24.11.2016, 11:10
  #31

Не по теме:

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

0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,135
Записей в блоге: 2
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) работает асинхронно, поэтому данные внутри прокси могут не соответствовать тому запросу, на который мы отвечаем. Тогда нужно как-то хранить данные, и тогда нужно как-то давать понять прокси на какой запрос мы отвечаем. В этом случае профит от прокси теряется. Было все синхронно было бы проще.
1
Модератор
3388 / 2160 / 352
Регистрация: 13.01.2012
Сообщений: 8,379
24.11.2016, 12:27 33
Цитата Сообщение от Kastaneda Посмотреть сообщение
т.к. теоретически cast может быть невалидным
с чего бы это вдруг? вы реализацию на лету можете поменять между приемом и ответом одного сообщения?

Добавлено через 2 минуты
...даже если так базовый класс может поддерживать единую для всех реализаций функцию "узнай какого типа сообщение внутри меня" - если при ответе мы видим что сообщение сформировано другой реализацией очевидно был горячий рестарт и нам не остается ничего кроме как отбросить такое сообщение так как мы не знаем как с ним работать
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
24.11.2016, 13:12 34
Цитата Сообщение от Kastaneda Посмотреть сообщение
Тогда нужно как-то хранить данные, и тогда нужно как-то давать понять прокси на какой запрос мы отвечаем.
Хранить данные обязательно. И на AMQP же хранится id, если только id не является "командной" информацией. Давать понять придётся так же как Вы собираетесь делать сейчас, но возможно более явно, что просто проще.
Цитата Сообщение от Kastaneda Посмотреть сообщение
В этом случае профит от прокси теряется.
Профит от тяжелой парты прокси компонента только в том, что есть возможность сохранить программное обеспечение RPC совершенно нетронутым. То есть он действительно сможет "не знать". Но у такого неведения есть немалая цена. Это правда.
Это не потому, что фраза "знание умножает скорбь" неправа. Это потому что и незнание её тоже, мягко говоря, не уменьшает. Только мы с Вами можем её уменьшить. Например, тиснуть вот такой смайлик:
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
28.11.2016, 17:53 35
Kastaneda, очень долго читал, но так до конца и не понял. Вы можете словесно-схематично+абстрактно (без аббривеатур, а на уровне класс1/черный_ящик1) показать желаемую схему работы в контексте обмена данными?
1
28.11.2016, 17:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.11.2016, 17:53
Помогаю со студенческими работами здесь

Почему высокий уровень на пине?
&lt;Изображение удалено&gt; Кароч вот код начальной инициализации. Вопрос- почему пин РА0 находиться в...

Реагирование программы на высокий уровень шума
Хочу сделать мини утилиту сидящая в трее и которая бы оповещала, звуком или просто надписью когда...

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

Работа со звуком более или менее низкий уровень. Получить уровень сигнала микрофона
Доброго дня или ночи. Вобщем товарищи дело такое. предо мной стоит задача определять уровень шума...

Определить, в какие дни наблюдался самый высокий уровень воды в реке
Ежедневно в течение июня измерялся уровень воды в реке Урал, данные занесли в одномерный массив....

Оптимальная реализации конкретной части дизайна
Всем доброго времени суток! На форуме я первый день, поэтому если что-то не так сделал, то...


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

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru