Is it possible to create a mailbox agent that only sometimes posts replies? From the looks of it, It seems to me that you have to always send an async reply channel if you want to ever post replies.
For my use case I'd really like to be able to have the flexibility that some messages only need to be delivered to the agent, whereas other messages I'd like to get either a synchronous or asynchronous reply back.
I'm not sure if I understand the question correctly - but you can certainly use a discriminated union as a type of your messages. Then you can have some cases (message types) that contain AsyncReplyChannel<T>
and some other messages that do not carry it (and do not require a reply).
For example, for a simple agent that adds numbers, you can have Add
(which does not need response) and Get
which does need a response. In addition, Get
carries a Boolean that specifies whether we should reset the state back to zero:
type Message =
| Add of int
| Get of bool * AsyncReplyChannel<int>
The agent then receives messages repeatedly and if the message is Get
then it sends a reply:
let counter = MailboxProcessor.Start(fun inbox ->
let rec loop count = async {
let! msg = inbox.Receive()
match msg with
| Add n -> return! loop (count + n) // Just update the number
| Get (reset, repl) ->
repl.Reply(count) // Reply to the caller
let count = if reset then 0 else count // get new state
return! loop count } // .. and continue in the new state
loop 0 )
You can then use Post
method to send message that does not require a reply and PostAndReply
to send a message that returns something via an async reply channel:
counter.Post(Add 10)
counter.PostAndReply(fun r -> Get(true, r))
counter.PostAndReply(fun r -> Get(false, r))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With