MailboxProcessor
Agents serialize access to state. Each processes one message at a time. Use inbox.Scan/TryReceive for selective or timed receives. For distributed actors, see Akka.NET (with Akkling for F#) or Orleans.
// Agents: message-processing actors with private state (no locks needed)
type CounterMsg =
| Increment of int
| Get of AsyncReplyChannel<int>
| Reset
let counter =
MailboxProcessor.Start(fun inbox ->
let rec loop count = async {
let! msg = inbox.Receive()
match msg with
| Increment n -> return! loop (count + n)
| Get reply ->
reply.Reply count
return! loop count
| Reset -> return! loop 0
}
loop 0)
counter.Post (Increment 5)
counter.Post (Increment 3)
counter.PostAndReply Get // 8
counter.PostAndAsyncReply Get |> Async.RunSynchronously
counter.Post Reset
// A bank account agent that serializes concurrent operations
type AccountMsg =
| Deposit of decimal
| Withdraw of decimal * AsyncReplyChannel<Result<decimal, string>>
| Balance of AsyncReplyChannel<decimal>
let account = MailboxProcessor.Start(fun inbox ->
let rec loop balance = async {
match! inbox.Receive() with
| Deposit amt -> return! loop (balance + amt)
| Withdraw (amt, reply) when amt <= balance ->
reply.Reply (Ok (ba
…