scalaadvanced
Akka Actor System Basics
Build concurrent applications with Akka actors: message passing, behavior switching, and supervision.
scalaPress ⌘/Ctrl + Shift + C to copy
import akka.actor.typed.{ActorRef, ActorSystem, Behavior}
import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext, Behaviors}
// Message protocol
object Counter:
sealed trait Command
case object Increment extends Command
case object Decrement extends Command
case class GetCount(replyTo: ActorRef[Int]) extends Command
case object Reset extends Command
def apply(): Behavior[Command] =
Behaviors.setup(ctx => new Counter(ctx))
class Counter(ctx: ActorContext[Counter.Command])
extends AbstractBehavior[Counter.Command](ctx):
import Counter.*
private var count = 0
override def onMessage(msg: Command): Behavior[Command] = msg match
case Increment =>
count += 1
ctx.log.info(s"Incremented to $count")
this
case Decrement =>
count -= 1
ctx.log.info(s"Decremented to $count")
this
case GetCount(replyTo) =>
replyTo ! count
this
case Reset =>
count = 0
ctx.log.info("Reset")
this
// Functional style actor
object Greeter:
sealed trait Command
case class Greet(name: String, replyTo: ActorRef[String]) extends Command
def apply(): Behavior[Command] =
Behaviors.receive { (ctx, msg) =>
msg match
case Greet(name, replyTo) =>
ctx.log.info(s"Greeting $name")
replyTo ! s"Hello, $name!"
Behaviors.same
}
// Stateful actor with behavior switching
object Switch:
sealed trait Command
case object Toggle extends Command
case class GetState(replyTo: ActorRef[String]) extends Command
def apply(): Behavior[Command] = off()
private def on(): Behavior[Command] =
Behaviors.receive { (ctx, msg) =>
msg match
case Toggle =>
ctx.log.info("Switching OFF")
off()
case GetState(replyTo) =>
replyTo ! "ON"
Behaviors.same
}
private def off(): Behavior[Command] =
Behaviors.receive { (ctx, msg) =>
msg match
case Toggle =>
ctx.log.info("Switching ON")
on()
case GetState(replyTo) =>
replyTo ! "OFF"
Behaviors.same
}
// Guardian actor
object Guardian:
def apply(): Behavior[Nothing] =
Behaviors.setup[Nothing] { ctx =>
val counter = ctx.spawn(Counter(), "counter")
counter ! Counter.Increment
counter ! Counter.Increment
counter ! Counter.Increment
val switch = ctx.spawn(Switch(), "switch")
switch ! Switch.Toggle
switch ! Switch.Toggle
Behaviors.empty
}
@main def run(): Unit =
val system = ActorSystem(Guardian(), "demo")
Thread.sleep(1000)
system.terminate()Use Cases
- Concurrent message-passing systems
- Stateful service actors
- Behavior switching for state machines
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalaintermediate
Futures and Async Programming
Use Scala Futures for async operations: map, flatMap, recover, sequence, and race patterns.
Best for: Asynchronous API calls
#scala#futures
scalaintermediate
Parallel Processing with Collections
Process data in parallel using parallel collections, Future.traverse, and batched execution.
Best for: Speeding up CPU-bound operations
#scala#parallel
scalaadvanced
Akka Streams Data Processing
Build reactive data pipelines with Akka Streams: sources, flows, sinks, and graph DSL.
Best for: Reactive data pipeline processing
#scala#akka
scalaintermediate
Future Async Patterns
Work with Scala Futures: composition, error handling, timeout, retry, and parallel execution.
Best for: Asynchronous API calls
#scala#future