2 people like it.

Replying with exceptions in MailboxProcessor

Just a quick and dirty hack

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
open Microsoft.FSharp.Control

type Reply<'T> =
    | Success of 'T
    | Error of exn
with
    member e.Value =
        match e with
        | Success t -> t
        | Error e -> raise e

and ReplyChannel<'T> internal (rc : AsyncReplyChannel<Reply<'T>>) =
    member __.Reply (t : 'T) = rc.Reply <| Success t
    member __.ReplyWithError (e : exn) = rc.Reply <| Error e

and MailboxProcessor<'T> with
    member m.PostAndReply (msgB : ReplyChannel<'R> -> 'T) =
        m.PostAndReply(fun ch -> msgB (new ReplyChannel<_>(ch))).Value
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Control
type Reply<'T> =
  | Success of 'T
  | Error of exn
  member Value : 'T

Full name: Script.Reply<_>
union case Reply.Success: 'T -> Reply<'T>
union case Reply.Error: exn -> Reply<'T>
type exn = System.Exception

Full name: Microsoft.FSharp.Core.exn
val e : Reply<'T>
member Reply.Value : 'T

Full name: Script.Reply`1.Value
val t : 'T
val e : exn
val raise : exn:System.Exception -> 'T

Full name: Microsoft.FSharp.Core.Operators.raise
Multiple items
type ReplyChannel<'T> =
  internal new : rc:AsyncReplyChannel<Reply<'T>> -> ReplyChannel<'T>
  member Reply : t:'T -> unit
  member ReplyWithError : e:exn -> unit

Full name: Script.ReplyChannel<_>

--------------------
internal new : rc:AsyncReplyChannel<Reply<'T>> -> ReplyChannel<'T>
val rc : AsyncReplyChannel<Reply<'T>>
type AsyncReplyChannel<'Reply>
member Reply : value:'Reply -> unit

Full name: Microsoft.FSharp.Control.AsyncReplyChannel<_>
Multiple items
member ReplyChannel.Reply : t:'T -> unit

Full name: Script.ReplyChannel`1.Reply

--------------------
type Reply<'T> =
  | Success of 'T
  | Error of exn
  member Value : 'T

Full name: Script.Reply<_>
member AsyncReplyChannel.Reply : value:'Reply -> unit
val __ : ReplyChannel<'T>
member ReplyChannel.ReplyWithError : e:exn -> unit

Full name: Script.ReplyChannel`1.ReplyWithError
Multiple items
type MailboxProcessor<'Msg> =
  interface IDisposable
  new : body:(MailboxProcessor<'Msg> -> Async<unit>) * ?cancellationToken:CancellationToken -> MailboxProcessor<'Msg>
  member Post : message:'Msg -> unit
  member PostAndAsyncReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> Async<'Reply>
  member PostAndReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> 'Reply
  member PostAndTryAsyncReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> Async<'Reply option>
  member Receive : ?timeout:int -> Async<'Msg>
  member Scan : scanner:('Msg -> Async<'T> option) * ?timeout:int -> Async<'T>
  member Start : unit -> unit
  member TryPostAndReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> 'Reply option
  ...

Full name: Microsoft.FSharp.Control.MailboxProcessor<_>

--------------------
new : body:(MailboxProcessor<'Msg> -> Async<unit>) * ?cancellationToken:System.Threading.CancellationToken -> MailboxProcessor<'Msg>
val m : MailboxProcessor<'Msg>
member MailboxProcessor.PostAndReply : msgB:(ReplyChannel<'R> -> 'Msg) -> 'R

Full name: Script.PostAndReply
val msgB : (ReplyChannel<'R> -> 'Msg)
member MailboxProcessor.PostAndReply : msgB:(ReplyChannel<'R> -> 'Msg) -> 'R
member MailboxProcessor.PostAndReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> 'Reply
val ch : AsyncReplyChannel<Reply<'R>>
Raw view Test code New version

More information

Link:http://fssnip.net/mK
Posted:10 years ago
Author:Eirik Tsarpalis
Tags: mailboxprocessor