CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-typesafe-akka--akka-actor-2-11

Akka Actor provides the foundational Actor Model implementation for building concurrent, distributed, resilient and elastic applications with supervision hierarchies and location transparency.

Overview
Eval results
Files

actors-props.mddocs/

Actors and Props

The Actor trait defines the core behavior of all actors, while Props provides type-safe configuration for actor creation with deployment, dispatcher, and mailbox settings.

Capabilities

Actor Trait

Core actor behavior with message handling and lifecycle hooks.

import scala.annotation.unused

/**
 * Base trait for all actors defining core behavior and lifecycle  
 */
trait Actor {
  // Type alias to make Receive known in subclasses without import
  type Receive = Actor.Receive
  /** 
   * Message handling partial function - must be implemented
   * @return PartialFunction mapping messages to actions
   */
  def receive: Actor.Receive
  
  /**
   * Actor execution context providing access to system and self.
   * Initialized when actor is created - complex internal implementation.
   */
  implicit val context: ActorContext
  
  /**
   * Reference to this actor - MUST BE A VAL for proper initialization.
   * Marked final to prevent override.
   */
  implicit final val self: ActorRef
  
  /**
   * Sender of the current message being processed
   * @return ActorRef of sender, or deadLetters if no sender
   */
  final def sender(): ActorRef
  
  /**
   * Supervision strategy for child actors.
   * Default implementation returns SupervisorStrategy.defaultStrategy.
   * @return SupervisorStrategy defining fault handling
   */
  def supervisorStrategy: SupervisorStrategy = SupervisorStrategy.defaultStrategy
  
  /**
   * Called when actor is started - override for initialization.
   * Default implementation does nothing.
   */
  @throws(classOf[Exception])
  def preStart(): Unit = ()
  
  /**
   * Called when actor is stopped - override for cleanup.
   * Default implementation does nothing.
   */
  @throws(classOf[Exception])
  def postStop(): Unit = ()
  
  /**
   * Called before restart on crashed actor.
   * Default implementation stops all children and calls postStop().
   * @param reason - Exception that caused restart (unused in default implementation)
   * @param message - Message being processed when failure occurred (unused in default implementation)
   */
  @throws(classOf[Exception])
  def preRestart(@unused reason: Throwable, @unused message: Option[Any]): Unit = {
    context.children.foreach { child =>
      context.unwatch(child)
      context.stop(child)
    }
    postStop()
  }
  
  /**
   * Called after restart on new actor instance.
   * Default implementation calls preStart().
   * @param reason - Exception that caused restart (unused in default implementation)
   */
  @throws(classOf[Exception])
  def postRestart(@unused reason: Throwable): Unit = preStart()
  
  /**
   * Called for messages not handled by receive
   * @param message - Unhandled message
   */
  def unhandled(message: Any): Unit
}

object Actor {
  /**
   * Type alias for message handling function
   */
  type Receive = PartialFunction[Any, Unit]
  
  /**
   * Receive function that handles no messages
   */
  object emptyBehavior extends Receive {
    def isDefinedAt(x: Any) = false
    def apply(x: Any) = throw new UnsupportedOperationException("Empty behavior apply()")
  }
  
  /**
   * Receive function that ignores all messages
   */
  object ignoringBehavior extends Receive {
    def isDefinedAt(x: Any): Boolean = true
    def apply(x: Any): Unit = ()
  }
  
  /**
   * Sentinel value indicating no sender
   */
  final val noSender: ActorRef = null
}

Usage Examples:

import akka.actor._

// Basic actor implementation
class MyActor extends Actor {
  def receive = {
    case "hello" => sender() ! "Hello back!"
    case count: Int => 
      println(s"Received count: $count")
      if (count > 0) self ! (count - 1)
    case _ => unhandled(message)
  }
  
  override def preStart(): Unit = {
    println("MyActor started")
  }
  
  override def postStop(): Unit = {
    println("MyActor stopped")
  }
}

// Actor with state
class CounterActor extends Actor {
  private var count = 0
  
  def receive = {
    case "increment" => count += 1
    case "get" => sender() ! count
    case "reset" => count = 0
  }
}

Props Configuration

Immutable configuration for actor creation and deployment.

/**
 * Immutable configuration object for actor creation
 */
class Props private (
  val deploy: Deploy,
  val clazz: Class[_],
  val args: immutable.Seq[Any]
) {
  /**
   * Create new Props with custom dispatcher
   * @param dispatcher - Dispatcher ID from configuration
   * @return New Props with dispatcher setting
   */
  def withDispatcher(dispatcher: String): Props
  
  /**
   * Create new Props with custom mailbox
   * @param mailbox - Mailbox type from configuration  
   * @return New Props with mailbox setting
   */
  def withMailbox(mailbox: String): Props
  
  /**
   * Create new Props with deployment configuration
   * @param deploy - Deployment settings
   * @return New Props with deploy settings
   */
  def withDeploy(deploy: Deploy): Props
  
  /**
   * Create new Props with router configuration
   * @param routerConfig - Router configuration
   * @return New Props with routing
   */
  def withRouter(routerConfig: RouterConfig): Props
}

object Props {
  /**
   * Create Props from actor class (Scala API)
   * @tparam T - Actor type with ClassTag
   * @return Props for creating actors of type T
   */
  def apply[T <: Actor: ClassTag]: Props
  
  /**
   * Create Props from actor class with constructor arguments (Scala API)
   * @param creator - By-name parameter creating actor instance
   * @return Props for the creator function
   */
  def apply(creator: => Actor): Props
  
  /**
   * Create Props from Java class
   * @param actorClass - Java class extending Actor
   * @return Props for the actor class
   */
  def create(actorClass: Class[_ <: Actor]): Props
  
  /**
   * Create Props from Java class with constructor arguments
   * @param actorClass - Java class extending Actor
   * @param args - Constructor arguments
   * @return Props for actor class with arguments
   */
  def create(actorClass: Class[_ <: Actor], args: Any*): Props
  
  /**
   * Create Props from creator function (Java API)
   * @param creator - Creator function returning Actor
   * @return Props for the creator
   */
  def create(creator: Creator[Actor]): Props
  
  /**
   * Empty Props for no-arg actor construction
   */
  val empty: Props
}

Usage Examples:

import akka.actor._

// Simple Props creation
val props1 = Props[MyActor]
val props2 = Props(new MyActor)

// Props with constructor arguments  
class ParameterizedActor(name: String, value: Int) extends Actor {
  def receive = {
    case "getName" => sender() ! name
    case "getValue" => sender() ! value
  }
}

val props3 = Props(new ParameterizedActor("test", 42))

// Props with custom dispatcher and mailbox
val props4 = Props[MyActor]
  .withDispatcher("my-dispatcher")
  .withMailbox("priority-mailbox")

// Java API
val javaProps = Props.create(classOf[MyActor])
val javaPropsWithArgs = Props.create(classOf[ParameterizedActor], "test", 42)

Actor Creation Patterns

Common patterns for creating actors with different lifecycles and behaviors.

/**
 * Java-friendly actor base class
 */
abstract class AbstractActor extends Actor {
  /**
   * Create receive behavior using builder pattern
   * @return Receive behavior for this actor
   */
  def createReceive(): AbstractActor.Receive
  
  final def receive = createReceive()
}

object AbstractActor {
  /**
   * Builder for creating receive behavior
   */
  abstract class Receive {
    def build(): Actor.Receive
  }
}

/**
 * Legacy untyped actor base (deprecated)
 */
abstract class UntypedActor extends AbstractActor {
  /**
   * Handle received message
   * @param message - Received message
   */
  def onReceive(message: Any): Unit
  
  final def createReceive(): AbstractActor.Receive = {
    case msg => onReceive(msg)
  }
}

Usage Examples:

// AbstractActor with builder pattern
class JavaStyleActor extends AbstractActor {
  import akka.japi.pf.ReceiveBuilder
  
  def createReceive(): AbstractActor.Receive = {
    ReceiveBuilder.create()
      .match(classOf[String], (msg: String) => {
        println(s"Received string: $msg")
      })
      .match(classOf[Integer], (msg: Integer) => {
        println(s"Received integer: $msg")
      })
      .matchAny((msg: Any) => {
        println(s"Received unknown: $msg")
      })
      .build()
  }
}

Actor Logging Support

Traits for adding logging capabilities to actors.

/**
 * Mixin trait providing logging to actors
 */
trait ActorLogging { this: Actor =>
  /**
   * Logging adapter for this actor
   */
  def log: LoggingAdapter
}

/**
 * Mixin providing diagnostic logging with MDC support
 */
trait DiagnosticActorLogging extends Actor {
  /**
   * Diagnostic logging adapter
   */
  val log: DiagnosticLoggingAdapter
  
  /**
   * Mapped Diagnostic Context for current message
   * @param currentMessage - Message being processed
   * @return MDC map for logging context
   */
  def mdc(currentMessage: Any): MDC
}

Usage Examples:

// Actor with logging
class LoggingActor extends Actor with ActorLogging {
  def receive = {
    case msg =>
      log.info("Received message: {}", msg)
      // Process message
  }
}

// Actor with diagnostic logging
class DiagnosticActor extends Actor with DiagnosticActorLogging {
  def receive = {
    case msg =>
      log.info("Processing message")
      // Message processing
  }
  
  override def mdc(currentMessage: Any): MDC = {
    Map(
      "messageType" -> currentMessage.getClass.getSimpleName,
      "actorPath" -> self.path.toString
    )
  }
}

Types

/**
 * Deployment configuration for actors
 */
case class Deploy(
  path: String,
  config: Config,
  routerConfig: RouterConfig,
  scope: Scope,
  dispatcher: String,
  mailbox: String
) {
  def withDispatcher(dispatcher: String): Deploy
  def withMailbox(mailbox: String): Deploy
  def withRouterConfig(routerConfig: RouterConfig): Deploy
}

/**
 * Deployment scope (local, remote, cluster)
 */
sealed trait Scope
case object LocalScope extends Scope
case class RemoteScope(node: Address) extends Scope

/**
 * Factory for creating actors with specific constructor arguments
 */
trait IndirectActorProducer {
  def actorClass: Class[_ <: Actor]
  def produce(): Actor
}

Install with Tessl CLI

npx tessl i tessl/maven-com-typesafe-akka--akka-actor-2-11

docs

actor-system.md

actors-props.md

fsm.md

index.md

messaging-references.md

patterns-utilities.md

scheduling-timers.md

supervision.md

tile.json