简体   繁体   中英

Can I safely create a Thread in an Akka Actor?

I have an Akka Actor that I want to send "control" messages to. This Actor's core mission is to listen on a Kafka queue, which is a polling process inside a loop.

I've found that the following simply locks up the Actor and it won't receive the "stop" (or any other) message:

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? 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. 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

2) Hand over the message to the relevant actor

3) Send a message to itself to order to pull a new message

4) Hand it over...

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; 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). 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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