Пытаясь понять, как мыслить в терминах акторов, а не потоков. I Я немного озадачен следующим вариантом использования:
Рассмотрим систему, в которой есть процесс-производитель, который создает работу (например, путем чтения данных из файла), и ряд рабочих процессов, которые потребляют эту работу (например, путем анализа данные и запись их в базу данных). Скорость производства и потребления работы может варьироваться, и система должна оставаться устойчивой к этому. Например, если рабочие не могут успевать, производитель должен это обнаружить и, в конечном итоге, замедлить вниз или подождите.
Это довольно легко реализовать с помощью потоков:
val producer:Iterator[Work] = createProducer()
val queue = new LinkedBlockingQueue[Work](QUEUE_SIZE)
val workers = (0 until NUM_WORKERS) map { i =>
new Thread() {
override def run() = {
while (true) {
try {
// take next unit of work, waiting if necessary
val work = queue.take()
process(work)
}
catch {
case e:InterruptedException => return
}
}
}
}
}
// start the workers
workers.foreach(_.start())
while (producer.hasNext) {
val work = producer.next()
// add new unit of work, waiting if necessary
queue.put(work)
}
while (!queue.isEmpty) {
// wait until queue is drained
queue.wait()
}
// stop the workers
workers.foreach(_.interrupt())
В этой модели нет ничего плохого, и я успешно использовал ее раньше. Этот пример, вероятно, слишком многословен, поскольку использование Executor или CompletionService было бы хорошо подходят для этой задачи. Но мне нравится абстракция актеров, и я думаю, что ее легче рассуждать во многих случаях. Есть ли способ переписать этот пример с использованием акторов, особенно убедившись, что нет переполнения буфера (например, полные почтовые ящики, отброшенные сообщения и т. Д.)?