На LOR-е задали очень хороший вопрос:
...скажите пожалуйста как решается проблема с thread starvation если например какие-то актеры выполняют cpu intensive или blocking IO задачи, а каким-то другим актерам нужна высокая отзывчивость?
Написал развернутый ответ там же. Но, т.к. вопрос очень хороший, то имеет смысл продублировать ответ и здесь:
Эти вопросы решаются за счет создания такого количества диспетчеров, которое нужно приложению.
Т.е. в SO5 нет одного общего диспетчера, на котором будут работать все агенты (как в некоторых простых реализациях, где есть один общий thread-pool и все акторы запускаются на нитях из этого пула). В SO5 можно создать столько диспетчеров, сколько потребуется задаче. И выбрать при этом еще и подходящий тип диспетчера.
Сейчас «из коробки» есть такие диспетчеры:
- one_thread, все привязанные к диспетчеру агенты работают на одной общей нити;
- active_obj, каждый агент получает свою собственную рабочую нить;
- active_group, каждой отдельной группе агентов выделяется своя рабочая нить;
- thread_pool, привязанные к диспетчеру агенты распределяются между нитями из пула;
- adv_thread_pool, так же пул нитей на которых работают агенты, но если агент декларирует свои события как thread-safe, то несколько событий одного агента могут обрабатываться параллельно на соседних нитях пула.
За счет этого можно сделать, например, так:
- выделить one_thread-диспетчер для агента, который будет работать с MQ-шным сервером по AMQP (т.е. подписываться/читать/публиковать);
- выделить thread_pool-диспетчер для агентов, которые выполняют прикладную обработку полученных от MQ сообщений;
- выделить active_obj-диспетчер для агентов, которые будут выполнять операции с СУБД;
- выделить active_obj-диспетчер для агентов, который будут работать с подключенными к компьютеру устройствами (вроде HSM, SmartCard-ридерами, I/O-контроллерами и т.д.)
При этом программирование в агентах на SO5 не похоже на таковое в Erlang или CAF. Оно скорее напоминает SEDA-подход со стадийностью обработки прикладных задач. В SO5 под каждую стадию (I/O, DBMS, ext.device, etc) выделяется агент/группа агентов со своим диспетчером и своим рабочим контекстом. Агенты, которые занимаются только быстротечным диспатчингом запросов (т.е. получили сообщение, проанализировали куда оно идет, переслали, получили ответ, проанализировали, отправили дальше), собираются либо на единичных one_thread диспетчерах, либо в виде групп на active_group-диспетчерах, либо на одном-двух (adv_)thread_pool диспетчерах.
При этом важно отметить еще и то, что агенты и типы диспетчеров — это ортогональные друг другу понятия. Один и тот же агент, в зависимости от задачи, может быть привязан как к one_thread, так и к adv_thread_pool диспетчеру. В коде самого агента от этого ничего не изменится. Что так же сильно упрощает разработку софта с использованием SO5.
Комментариев нет:
Отправить комментарий