Миграция из параллелизма Java в параллелизм Scala

у меня довольно стандартный механизм в Java для решения проблемы:

  • рабочие элементы должны быть запланированы для выполнения в определенное время
  • каждый рабочий элемент должен затем ждать, когда условие станет истинным
  • рабочие элементы должны быть отменены

решение я использую выглядит следующим образом:

  1. есть однопоточный планировщик для планирования моих рабочих элементов
  2. есть ExecutorService (который может быть многопоточный)
  3. каждый запланированный рабочий элемент затем отправляет фактическую работу в ExecutorService. Вернувшийся Future кэшируется на карте. Служба завершения используется для удаления будущего из кэша после завершения работы
  4. элементы могут быть отменены через кэшированные фьючерсы

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

Так что теперь я кодирование в Scala и использование структуры actor. Предполагая, что мой рабочий элемент может быть инкапсулирован в событие, отправленное актеру:

  1. какой механизм я бы использовал для планирования рабочего элемента на определенное время?
  2. если рабочий элемент-это событие, отправленное актору, как я могу гарантировать, что пул резервных потоков больше, чем количество элементов, которые могут блокироваться одновременно
  3. как я могу вызвать ранее запланированный рабочий элемент отменили?

2 ответов


какой механизм я бы использовал для планирования рабочего элемента на определенное время?

Я бы использовал java.утиль.параллельный.Scheduledexecutorservice выполняет.

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

Это меня поражает как дизайном, который побеждает усилий parallelisation. Попробуйте минимизировать или устранить блокирование и глобальное состояние. Это барьеры для композиционности и масштабируемости. Например, рассмотрим наличие одного выделенного потока, который ожидает поступления файлов, а затем запускает события для актеров. Или посмотрите на java.nio для асинхронного неблокирующего ввода-вывода

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

Как я могу отменить ранее запланированный рабочий элемент?

ScheduledExecutorService фьючерсы возвращает. Что у вас есть не плохой дизайн в этом отношении. Соберите их на карте и позвоните в future.аннулировать.)(


У вас может быть актер планирования, который имеет список запланированных актеров и использует актер.receiveWithin () просыпаться каждую секунду или около того и отправлять сообщения актерам, которые готовы к выполнению. Актер планирования также может обрабатывать отмену. Другой вариант-позволить каждому актору обрабатывать собственное планирование непосредственно с помощью receiveWithin () вместо централизации планирования.

есть некоторые обсуждения по этому вопросу в блогепростой cron, как планировщик в Scala.