/*:#localized(key: "DistributedLocalActorRecap")
 # Recap: a local actor protects state in one process

 First, let's ground ourselves in what you already know from the chapter [Actors](Actors.playgroundchapter/Overview). An
 **actor** is a reference type that protects its own mutable state by
 serializing access: only one task touches its internals at a time, so you can't
 get a data race on that state. From outside, you reach its members with
 `await`.

 Here's a bank ledger as a local actor. A hundred concurrent deposits all land
 correctly, with no locks in sight.
 */
//#-editable-code
import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

actor Ledger {
    private var balance: Int = 0

    func deposit(_ amount: Int) {
        balance += amount
    }

    func currentBalance() -> Int {
        balance
    }
}

let ledger = Ledger()

Task {
    await withTaskGroup(of: Void.self) { group in
        for _ in 1...100 {
            group.addTask { await ledger.deposit(1) }
        }
    }
    print("Final balance: \(await ledger.currentBalance())")
    PlaygroundPage.current.finishExecution()
}
//#-end-editable-code
/*:#localized(key: "DistributedLocalActorRecap-2")
 **Watch it run:** you'll see `Final balance: 100`, every single time. A hundred
 tasks raced to mutate `balance`, but the actor let them in one at a time, so not
 a cent went missing. Hold onto that guarantee: a distributed actor keeps it, and
 stretches it across the network.

 * callout(Try it): Change `1...100` to `1...10_000`. The final balance still
 matches the count exactly, no cent lost, no matter how many tasks pile on.

 The key limitation: `ledger` lives in **one process**. Every task that touches
 it is running inside the same app, sharing the same memory. The moment the
 state needs to live somewhere else (another process, another device, a
 server), a plain actor can't reach it.

 [Previous](@previous)  |  page 2 of 9  |  [Next: From One Process to Many](@next)
 */
