Exponential backoff spaces out repeated actor restarts when a dependency, such as a database, is unresponsive or overloaded. Each retry waits longer than the previous one, up to a maximum delay. section 5.5.2
Recreating a database writer
A database writer recreates its connection after DbBrokenConnectionException. The first restart waits a few seconds; later restarts wait progressively longer until the maximum. Random delay prevents multiple writers from retrying simultaneously. After 15 seconds without backoff, the next delay returns to the minimum. section 5.5.2
Listing 5.6 DbWriter sketch implementation
object DbWriter {
sealed trait Command
final case class Line(time: Long, message: String, messageType: String)
extends Command
def apply(databaseUrl: String): Behavior[Command] =
supervisorStrategy { #1
Behaviors.setup[Command] { context =>
// creates connection using databaseUrl
Behaviors
.receiveMessage[Command] {
case Line(t, m, mt) =>
... #2
... #B #3
}
.receiveSignal {
case (_, PostStop) =>
... #1
case (_, PreRestart) =>
... #1
}
}
}
def supervisorStrategy(behavior: Behavior[Command]): Behavior[Command] = #4
Behaviors
.supervise {
Behaviors
.supervise(behavior)
.onFailure[UnexpectedColumnsException]
.SupervisorStrategy.resume
}
.onFailure[DbBrokenConnectionException](SupervisorStrategy
.restartWithBackoff(minBackoff = 3, maxBackoff = 30, randomFactor = 0.1)
.withResetBackoffAfter(15))
}
Use the database-writer sketch to locate the supervised actor whose setup creates the connection and whose stop or restart handlers prevent resource leaks. section 5.5.2







