scalaz stream:基于一个队列组合队列';s码

scalaz stream:基于一个队列组合队列';s码,scala,scalaz-stream,Scala,Scalaz Stream,在我的应用程序中,我有多达N个并行工作的消费者和一个生产者。消费者从生产者那里获取资源,完成他们的工作,将结果附加到一个updateQueue,并请求更多的资源。Producer最初有一些可用资源,可以通过应用updateQueue中的更新来生成更多资源。在向使用者发送新资源之前,应用所有可用更新非常重要。我曾尝试使用以下生成器,每当消费者发出请求时,请求“批量”更新,并在ticketQueue中留出新资源(消费者不需要,但以后可能会被其他消费者请求): def updatesOrFresh:P

在我的应用程序中,我有多达N个并行工作的消费者和一个生产者。消费者从生产者那里获取资源,完成他们的工作,将结果附加到一个
updateQueue
,并请求更多的资源。Producer最初有一些可用资源,可以通过应用
updateQueue
中的更新来生成更多资源。在向使用者发送新资源之前,应用所有可用更新非常重要。我曾尝试使用以下生成器,每当消费者发出请求时,请求“批量”更新,并在
ticketQueue
中留出新资源(消费者不需要,但以后可能会被其他消费者请求):

def updatesOrFresh:Process[任务,Seq[优化结果]\/Unit]=
Process.await(updateQueue.size.continuous.take(1.runLast){
案例部分(大小)=>
println(s“尺寸:$size”)
如果(大小==0)
wye(updateQueue.dequeueAvailable,ticketQueue.dequeue)(wye.other)
其他的
updateQueue.dequeueAvailable.map(queue.left[Unit])
}.take(1)+进程.suspend(updatesOrFresh)
它不工作-最初可用的资源从
ticketQueue.dequeue
发出,然后它似乎在
wye
上阻塞,记录:

size: 0
<<got ticket>>
size: 0
<<got ticket>>
size: 0   // it appears the updateQueue did not receive the consumer output yet, but I can live with that, it should grab an update from the wye anyway
<<blocks>>
它按预期工作(尽管没有“在发出新资源之前应用更新”保证)。如何确保在正确的时间应用更新


编辑:我已使用以下代码解决了此问题:

  val updatesOrFresh: Process[Task, Seq[OptimizerResult] \/ Unit] =
    Process.repeatEval {
      for {
        sizeOpt <- updateQueue.size.continuous.take(1).runLast
        nextOpt <-
          if (sizeOpt.getOrElse(???) == 0)
            wye(updateQueue.dequeueAvailable, ticketQueue.dequeue)(wye.either).take(1).runLast
          else
            updateQueue.dequeueAvailable.map(_.left[Unit]).take(1).runLast
      } yield nextOpt.getOrElse(???)
    }
val updatesOrFresh:Process[Task,Seq[OptimizerResult]\/Unit]=
过程重复评估{
为了{
西泽普特
  val updatesOrFresh: Process[Task, Seq[OptimizerResult] \/ Unit] =
    Process.repeatEval {
      for {
        sizeOpt <- updateQueue.size.continuous.take(1).runLast
        nextOpt <-
          if (sizeOpt.getOrElse(???) == 0)
            wye(updateQueue.dequeueAvailable, ticketQueue.dequeue)(wye.either).take(1).runLast
          else
            updateQueue.dequeueAvailable.map(_.left[Unit]).take(1).runLast
      } yield nextOpt.getOrElse(???)
    }