我可以安全地在Akka演员中创建一个Thread吗?

时间:2016-07-20 16:37:08

标签: scala akka

我有一个Akka演员,我想发送"控制"消息到。 这个Actor的核心任务是监听Kafka队列,这是一个循环内的轮询过程。

我发现以下内容只是锁定了Actor并且它不会收到" stop" (或任何其他)消息:

class Worker() extends Actor {
  private var done = false

  def receive = {
    case "stop" => 
      done = true
      kafkaConsumer.close()
    // other messages here
  }

  // Start digesting messages!
  while (!done) {
    kafkaConsumer.poll(100).iterator.map { cr: ConsumerRecord[Array[Byte], String] =>
      // process the record
      ), null)
    }
  }
}

我可以将循环包装在由Actor启动的Thread中,但是从Actor内部启动Thread是否可以/安全?还有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

基本上你可以记住,这个演员会被阻挡,规则的拇指永远不会阻挡演员。如果您仍想这样做,请确保此actor在单独的线程池中运行,而不是本机线程池,因此您不会影响Actor系统性能。另一种方法是将消息发送给自己以轮询新消息。

1)接收订单以从kafka

轮询消息

2)交出来     给相关演员的消息

3)向自己发送消息以进行订购     拉一条新消息

4)交出来......

代码明智:

case object PollMessage

class Worker() extends Actor {
  private var done = false

  def receive = {
    case PollMessage ⇒ {
      poll()
      self ! PollMessage
    }
    case "stop" =>
      done = true
      kafkaConsumer.close()
    // other messages here
  }

  // Start digesting messages!

  def poll() = {
    kafkaConsumer.poll(100).iterator.map { cr: ConsumerRecord[Array[Byte], String] =>
      // process the record
      ), null)
    }
  }

}

我不确定如果你继续阻止演员,你会收到停止信息。

答案 1 :(得分:0)

添加@Louis F.答案;根据您的演员的配置,他们将丢弃他们收到的所有消息,如果他们在他们忙碌的特定时刻或将他们放入邮箱也称为队列,并且稍后将处理消息(通常以FIFO方式)。但是,在这种特殊情况下,您使用function getNextRecurrenceDate(recurrenceVo,rule){ var startDate = new Date(recurrenceVo.recurrenceRangeVO.startDate); var today = new Date(); var calculatedDate = null; if(today.getTime() <= startDate.getTime()){ return startDate; }else{ //#rrule_after - when I debug the code and comes to this function execution, my application stucks/halts for long time and does not response at all calculatedDate = rule.after(today,true); // this is temporary code I have written to overcome the problem of daily weekday recurrence if(calculatedDate && recurrenceVo.dailyRecurrenceVO && recurrenceVo.dailyRecurrenceVO.everyWeekDay && calculatedDate.getDay() > 4){ calculatedDate.setDate(calculatedDate.getDate() + (7 - calculatedDate.getDay())); } } return (calculatedDate)?calculatedDate:''; } function getDailyNextRecurrenceDate(recurrenceVo){ var rule = new RRule({ freq: RRule.DAILY, interval: recurrenceVo.dailyRecurrenceVO.numberofDays, dtstart: new Date(recurrenceVo.recurrenceRangeVO.startDate) }) if(recurrenceVo.recurrenceRangeVO.endCount){ rule.options.count = recurrenceVo.recurrenceRangeVO.endCount; } if(recurrenceVo.dailyRecurrenceVO.everyWeekDay){ rule.options.interval = 1; // When I remove this code then all working fine and application not halting at all rule.options.byweekday = [RRule.MO, RRule.TU, RRule.WE, RRule.TH, RRule.FR] } if(recurrenceVo.recurrenceRangeVO.endDate){ rule.options.until = new Date(recurrenceVo.recurrenceRangeVO.endDate); } var nextRecDate = getNextRecurrenceDate(recurrenceVo,rule); return nextRecDate?nextRecDate.setHours(0,0,0,0):''; } 充斥着演员,并且您无法保证不会丢弃您的消息 - 这似乎发生在您的情况下。