简体   繁体   English

我可以在Akka Actor中安全地创建线程吗?

[英]Can I safely create a Thread in an Akka Actor?

I have an Akka Actor that I want to send "control" messages to. 我有一个要发送“控制”消息的Akka演员。 This Actor's core mission is to listen on a Kafka queue, which is a polling process inside a loop. 该Actor的核心任务是侦听Kafka队列,该队列是循环内的轮询过程。

I've found that the following simply locks up the Actor and it won't receive the "stop" (or any other) message: 我发现以下内容只是将Actor锁定,并且不会收到“停止”(或任何其他)消息:

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)
    }
  }
}

I could wrap the loop in a Thread started by the Actor, but is it ok/safe to start a Thread from inside an Actor? 我可以将循环包装在Actor启动的Thread中,但是从Actor内部启动Thread可以吗? Is there a better way? 有没有更好的办法?

Basically you can but keep in mind that this actor will be blocking and a thumb of rule is to never block inside actors. 基本上,您可以但要记住,此参与者将被阻止,并且经验法则是从不阻止参与者内部。 If you still want to do this, make sure that this actor runs in a separate thread pool than the native one so you don't affect Actor System performances. 如果仍要执行此操作,请确保此Actor在与本机线程池不同的线程池中运行,以免影响Actor系统的性能。 One another way to do it would be to send messages to itself to poll new messages. 另一种方法是将消息发送到自身以轮询新消息。

1) receive a order to poll a message from kafka 1)从Kafka收到命令以轮询消息

2) Hand over the message to the relevant actor 2)将消息移交给相关演员

3) Send a message to itself to order to pull a new message 3)向自己发送一条消息以命令发送一条新消息

4) Hand it over... 4)移交...

Code wise : 明智的代码:

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)
    }
  }

}

I am not sure though that you will ever receive the stop message if you continuously block on the actor. 我不确定如果您继续阻止演员,您是否会收到停止消息。

Adding @Louis F. answer; 添加@Louis F.答案; depending on the configuration of your actors they will either drop all messages that they receive if at the given moment they are busy or put them in a mailbox aka queue and the messages will be processed later (usually in FIFO manner). 根据参与者的配置,如果他们在给定的时刻忙碌,他们将丢弃他们收到的所有消息,或者将它们放入邮箱队列(又名邮箱),消息将在以后进行处理(通常以FIFO方式)。 However, in this particular case you are flooding the actor with PollMessage and you have no guarantee that your message will not be dropped - which appears to happen in your case. 但是,在这种情况下,您将用PollMessage充斥演员,并且不能保证不会删除您的消息-在您的情况下似乎会发生这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM