Переход от потоковой модели к акторам

Пытаясь понять, как мыслить в терминах акторов, а не потоков. 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 было бы хорошо подходят для этой задачи. Но мне нравится абстракция актеров, и я думаю, что ее легче рассуждать во многих случаях. Есть ли способ переписать этот пример с использованием акторов, особенно убедившись, что нет переполнения буфера (например, полные почтовые ящики, отброшенные сообщения и т. Д.)?

7
задан toluju 11 November 2010 в 21:15
поделиться