суббота, 17 января 2015 г.

[prog.c++.sobjectizer] Реализация дедлайнов для сообщений своими руками

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

В связи с этим возник резонный вопрос: если все так туго идет, то туда ли вообще попали? И нужно ли продолжать? Может быть такого же эффекта достичь уже имеющимися средствами?

Для одного из описанных месяц назад сценариев, похоже, можно обойтись тем, что уже есть в SObjectizer.

Речь идет о случае, когда агент S отсылает сообщения-запросы агенту R, которые должны быть обработаны за указанное время. А если они не обработаны, то должны быть проигнорированы. Такого эффекта вполне можно достичь, не модифицируя ядро SObjectizer. Как минимум двумя простыми способами.

Оба способа базируются на том, что внутри самого прикладного сообщения заводится поле, обозначающее дедлайн для сообщения (скорее всего это должна быть абсолютная временная метка, например, сообщение должно быть обработано до 17:45:13). Инициатор сообщения, агент S, ответственен за выставление этого дедлайна.

Первый способ -- тупой контроль за дедлайном внутри агента R при получении сообщения-запроса. Т.е. как только R получает новый запрос, он первым делом проверяет наступление дедлайна. Если дедлайн уже наступил, то сообщение не обрабатывается, а сразу же отсылается отрицательный ответ.

Второй способ -- это разделение агента R на два: Rc (collector) и Rp (performer). Агент Rc собирает сообщения-запросы и выстраивает их в очередь. Агент Rp выполняет очередной запрос и обращается к Rc за следующим запросом, агент Rc в ответ выдает Rp первый запрос из очереди. Пока Rp выполняет запросы агент Rc может отслеживать дедлайны находящихся в его очереди запросов. И выбрасывать те их них, для которых дедлайн наступил.

Преимущество второго способа еще и в том, что Rc может иметь приоритетную очередь. И очередной запрос от S может попасть либо в конец очереди, либо в ее начало, в зависимости от приоритета запроса. В реальной жизни это может запросто понадобиться, например, вот в такой ситуации:

Есть несколько агентов S: Sonline и Sbulk. Агент Sonline обрабатывает запросы из online-систем (например, запросы из Интернет-магазинов или от банкоматов). Поэтому для своих запросов Sonline выставляет небольшое время жизни, например, не более 30 секунд на всю операцию. Агент Sbulk обрабатывает запросы из offline-систем (например, оплата по расписанию), поэтому такие запросы можно выполнять дольше, отводя на всю операцию до нескольких минут. При этом, если к агенту Rc идет большой поток запросов от Sbulk и время от времени приходят единичные запросы от Sonline, то запросы от Sonline нужно обрабатывать в первую очередь.

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

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

Отправить комментарий