Re: Erlang avalanche
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 14.12.06 12:37
Оценка: 41 (4) +3
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Ну я надеюсь, я достаточно подробно пояснил, почему я считаю, что Эрланг невозможен под jvm/.net? Хочу правильно поставить акцент: я не отрицаю возможность lightweight библиотеки, я всего лишь навсего очень-очень сильно сомневаюсь, что она может составить конкуренцию Эрлангу на _его_ поле боя и на смежных площадях:


Уважаемые коллеги, обсуждающие, как аналогичные задачи можно успешно решать за счет очередей сообщений и пулов потоков. Мне кажется, вы недооцениваете одной важной вещи, которую предоставляет поход Erlang-а. Если упустить ее из виду, то очередь сообщений действительно может успешно использоваться (равно как и язык ассемблера в умелых руках). Разница всего лишь в цене и в возможностях.

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

В качестве примера возьмем гипотетическую доставку подписчикам RSDN текстов новых постов в виде e-mail сообщений (пример актуальный кстати, т.к. изрядный процент сообщений теряется). Предположим, что процедура доставки одного сообщения одному абоненту оформляется в виде самостоятельного процесса. Он использует механизм гарантированной доставки, повторяя попытки отсылки сообщения с возрастающим тайм-аутом после каждой неудачи. После N неудачных попыток процесс просто завершает свою работу ("на нет и суда нет"). Реализовать такой процесс в виде одного for-а не составляет труда (извините, пример не на Erlang-е, а на псевдо-языке):
deliver_message( post, recipient )
{
  for(i = 0; i != N; ++i )
  {
    result = try_deliver( post, recipient );
    if( ok != result )
    {
      // Если временная проблема доставки, то есть
      // смысл повторить ее позже.
      if( can_be_delivered_later( result ) )
        sleep( (i+1)*TIMEOUT );
      else
        // Если SMTP сервера нет или он говорит, что
        // такого получателя нет, то просто прекращаем
        // дальнейшие попытки.
        die( post, recipient, THESE_STUPID_BEES_MAKE_INVALID_HONEY );
    }
    else
      // Сообщение отправлено.
      die( post, recipient, HAVE_A_NICE_DAY );
}

Функция die может помечать в базе, что сообщение на данного абонента доставлять больше не нужно (для корректного продолжения работы после рестартов).

Создать такой процесс и отладить его -- нет проблем, все весьма тривиально. Причем run-time Erlang-а гарантирует, что система не ляжет, даже если в ней одновременно будут крутиться, скажем 500K таких процессов.

А вот альтернативные решения требуют несколько больших усилий. Самый простой вариант -- рескан с каким-то периодом базы в поиске пар сообщение/абонент, которым нужно произвести доставку. Но для того, чтобы протестировать его под нагрузкой придется сильно попотеть, набивая тестовую БД и имитируя различные исходы доставки сообщения. А так же верификации результатов тестирования.

Чуть более сложный вариант -- организация каждой пары сообщение/абонент в виде объекта. Этот объект ставится в очередь. Когда какая-то из нитей рабочего пула извлекает такой объект, она выполняет очередную попытку доставки, затем анализирует разультат доставки и принимает решение о том, что делать дальше. Здесь нужно придумывать, как ставить в очереди "отложенные" объекты, время повторной доставки которых далеко "в будущем" -- ведь вытащив такую заявку из вершины очереди рабочая нить должна понять, что еще рано, вернуть объект обратно и заснуть "до лучших" времен. Нужно самим делать механизм "прибивания" рабочих нитей которые из-за каких-то сбоев в функции try_deliver не возвращаются из обрабоки очередного сообщения.


Вот как-то так. Или я что-то не правильно про Erlang понял?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.