7 people like it.
Like the snippet!
Poor man's distributed actors
Knocked together a bare-minimum TCP wrapper for MailboxProcessor. Not intended for production.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
|
module Nessos.Vagrant.Tests.TcpActor
// mini distributed actor implementation
open System
open System.Net
open System.Net.Sockets
open System.IO
open System.Threading
open System.Threading.Tasks
open Microsoft.FSharp.Control
open Nessos.FsPickler
type AsyncBuilder with
member __.Bind(f : Task<'T>, g : 'T -> Async<'S>) = __.Bind(Async.AwaitTask f, g)
member __.Bind(f : Task, g : unit -> Async<'S>) = __.Bind(f.ContinueWith ignore, g)
type Stream with
member s.AsyncWriteBytes (bytes : byte []) =
async {
do! s.WriteAsync(BitConverter.GetBytes bytes.Length, 0, 4)
do! s.WriteAsync(bytes, 0, bytes.Length)
do! s.FlushAsync()
}
member s.AsyncReadBytes(length : int) =
let rec readSegment buf offset remaining =
async {
let! read = s.ReadAsync(buf, offset, remaining)
if read < remaining then
return! readSegment buf (offset + read) (remaining - read)
else
return ()
}
async {
let bytes = Array.zeroCreate<byte> length
do! readSegment bytes 0 length
return bytes
}
member s.AsyncReadBytes() =
async {
let! lengthArr = s.AsyncReadBytes 4
let length = BitConverter.ToInt32(lengthArr, 0)
return! s.AsyncReadBytes length
}
// existentially pack reply channels
type private IReplyChannelContainer<'T> =
abstract PostWithReply : MailboxProcessor<'T> -> Async<obj>
and private ReplyChannelContainer<'T, 'R>(msgB : AsyncReplyChannel<'R> -> 'T) =
interface IReplyChannelContainer<'T> with
member __.PostWithReply (mb : MailboxProcessor<'T>) = async {
let! r = mb.PostAndAsyncReply msgB
return r :> obj
}
type private ServerRequest<'T> =
| Post of 'T
| PostWithReply of IReplyChannelContainer<'T>
and private ServerResponse =
| Acknowledge
| Reply of obj
| Fault of exn
type TcpActor<'T> (mailbox : MailboxProcessor<'T>, endpoint : IPEndPoint, ?pickler : FsPickler) =
let pickler = match pickler with None -> new FsPickler() | Some p -> p
let listener = new TcpListener(endpoint)
let rec serverLoop () = async {
try
let! (client : TcpClient) = listener.AcceptTcpClientAsync()
use client = client
use stream = client.GetStream()
let! (bytes : byte []) = stream.AsyncReadBytes()
let! response = async {
try
let request = pickler.UnPickle<ServerRequest<'T>> bytes
match request with
| Post msg ->
do mailbox.Post msg
return Acknowledge
| PostWithReply rcc ->
let! reply = rcc.PostWithReply mailbox
return Reply reply
with e -> return Fault e
}
let bytes = pickler.Pickle response
do! stream.AsyncWriteBytes bytes
with e -> printfn "Server error: %A" e
return! serverLoop ()
}
let cts = new CancellationTokenSource()
do
listener.Start()
Async.Start(serverLoop (), cts.Token)
member __.Stop () = cts.Cancel() ; listener.Stop()
member __.MailboxProcessor = mailbox
member __.GetTcpClient () = new TcpActorClient<'T>(endpoint, pickler)
and TcpActorClient<'T>(serverEndpoint : IPEndPoint, ?pickler : FsPickler) =
let pickler = match pickler with None -> new FsPickler() | Some p -> p
let sendRequest (request : ServerRequest<'T>) = async {
use client = new TcpClient()
do! client.ConnectAsync(serverEndpoint.Address, serverEndpoint.Port)
use stream = client.GetStream()
let bytes = pickler.Pickle request
do! stream.AsyncWriteBytes bytes
let! (reply : byte []) = stream.AsyncReadBytes()
return pickler.UnPickle<ServerResponse> reply
}
member __.PostAsync (msg : 'T) = async {
let! response = sendRequest <| Post msg
match response with
| Acknowledge -> return ()
| Reply o -> return failwithf "TcpActor: invalid response '%O'." o
| Fault e -> return raise e
}
member __.PostAndReplyAsync (msgB : AsyncReplyChannel<'R> -> 'T) = async {
let wrapper = new ReplyChannelContainer<'T,'R>(msgB)
let! response = sendRequest <| PostWithReply wrapper
match response with
| Reply (:? 'R as r) -> return r
| Reply o -> return failwithf "TcpActor: invalid response '%O'." o
| Acknowledge -> return failwith "TcpActor: invalid response."
| Fault e -> return raise e
}
member __.Post (msg : 'T) = __.PostAsync msg |> Async.RunSynchronously
member __.PostAndReply (msgB) = __.PostAndReplyAsync msgB |> Async.RunSynchronously
type TcpActor private () =
static let parseEndpoint (endpoint : string) =
let tokens = endpoint.Split(':')
if tokens.Length <> 2 then raise <| new FormatException("invalid endpoint")
let ipAddr = Dns.GetHostAddresses(tokens.[0]).[0]
let port = int <| tokens.[1]
new IPEndPoint(ipAddr, port)
static member Create<'T>(behaviour : MailboxProcessor<'T> -> Async<unit>, ipEndPoint : IPEndPoint, ?pickler : FsPickler) =
let mailbox = MailboxProcessor.Start behaviour
new TcpActor<'T>(mailbox, ipEndPoint, ?pickler = pickler)
static member Create<'T>(behaviour : MailboxProcessor<'T> -> Async<unit>, ipEndPoint : string, ?pickler : FsPickler) =
TcpActor.Create(behaviour, parseEndpoint ipEndPoint, ?pickler = pickler)
static member Connect<'T>(serverEndPoint : IPEndPoint, ?pickler : FsPickler) =
new TcpActorClient<'T>(serverEndPoint, ?pickler = pickler)
static member Connect<'T>(serverEndPoint : string, ?pickler : FsPickler) =
new TcpActorClient<'T>(parseEndpoint serverEndPoint, ?pickler = pickler)
|
namespace Nessos
namespace Nessos.Vagrant
namespace Nessos.Vagrant.Tests
module TcpActor
from Nessos.Vagrant.Tests
namespace System
namespace System.Net
namespace System.Net.Sockets
namespace System.IO
namespace System.Threading
namespace System.Threading.Tasks
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Control
namespace Nessos.FsPickler
type AsyncBuilder =
private new : unit -> AsyncBuilder
member Bind : computation:Async<'T> * binder:('T -> Async<'U>) -> Async<'U>
member Combine : computation1:Async<unit> * computation2:Async<'T> -> Async<'T>
member Delay : generator:(unit -> Async<'T>) -> Async<'T>
member For : sequence:seq<'T> * body:('T -> Async<unit>) -> Async<unit>
member Return : value:'T -> Async<'T>
member ReturnFrom : computation:Async<'T> -> Async<'T>
member TryFinally : computation:Async<'T> * compensation:(unit -> unit) -> Async<'T>
member TryWith : computation:Async<'T> * catchHandler:(exn -> Async<'T>) -> Async<'T>
member Using : resource:'T * binder:('T -> Async<'U>) -> Async<'U> (requires 'T :> IDisposable)
...
Full name: Microsoft.FSharp.Control.AsyncBuilder
member AsyncBuilder.Bind : f:Task<'T> * g:('T -> Async<'S>) -> Async<'S>
Full name: Nessos.Vagrant.Tests.TcpActor.Bind
val f : Task<'T>
Multiple items
type Task =
new : action:Action -> Task + 7 overloads
member AsyncState : obj
member ContinueWith : continuationAction:Action<Task> -> Task + 9 overloads
member CreationOptions : TaskCreationOptions
member Dispose : unit -> unit
member Exception : AggregateException
member Id : int
member IsCanceled : bool
member IsCompleted : bool
member IsFaulted : bool
...
Full name: System.Threading.Tasks.Task
--------------------
type Task<'TResult> =
inherit Task
new : function:Func<'TResult> -> Task<'TResult> + 7 overloads
member ContinueWith : continuationAction:Action<Task<'TResult>> -> Task + 9 overloads
member Result : 'TResult with get, set
static member Factory : TaskFactory<'TResult>
Full name: System.Threading.Tasks.Task<_>
--------------------
Task(action: Action) : unit
Task(action: Action, cancellationToken: CancellationToken) : unit
Task(action: Action, creationOptions: TaskCreationOptions) : unit
Task(action: Action<obj>, state: obj) : unit
Task(action: Action, cancellationToken: CancellationToken, creationOptions: TaskCreationOptions) : unit
Task(action: Action<obj>, state: obj, cancellationToken: CancellationToken) : unit
Task(action: Action<obj>, state: obj, creationOptions: TaskCreationOptions) : unit
Task(action: Action<obj>, state: obj, cancellationToken: CancellationToken, creationOptions: TaskCreationOptions) : unit
--------------------
Task(function: Func<'TResult>) : unit
Task(function: Func<'TResult>, cancellationToken: CancellationToken) : unit
Task(function: Func<'TResult>, creationOptions: TaskCreationOptions) : unit
Task(function: Func<obj,'TResult>, state: obj) : unit
Task(function: Func<'TResult>, cancellationToken: CancellationToken, creationOptions: TaskCreationOptions) : unit
Task(function: Func<obj,'TResult>, state: obj, cancellationToken: CancellationToken) : unit
Task(function: Func<obj,'TResult>, state: obj, creationOptions: TaskCreationOptions) : unit
Task(function: Func<obj,'TResult>, state: obj, cancellationToken: CancellationToken, creationOptions: TaskCreationOptions) : unit
val g : ('T -> Async<'S>)
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken
Full name: Microsoft.FSharp.Control.Async
--------------------
type Async<'T>
Full name: Microsoft.FSharp.Control.Async<_>
val __ : AsyncBuilder
member AsyncBuilder.Bind : f:Task * g:(unit -> Async<'S>) -> Async<'S>
member AsyncBuilder.Bind : f:Task<'T> * g:('T -> Async<'S>) -> Async<'S>
member AsyncBuilder.Bind : computation:Async<'T> * binder:('T -> Async<'U>) -> Async<'U>
static member Async.AwaitTask : task:Task<'T> -> Async<'T>
member AsyncBuilder.Bind : f:Task * g:(unit -> Async<'S>) -> Async<'S>
Full name: Nessos.Vagrant.Tests.TcpActor.Bind
val f : Task
val g : (unit -> Async<'S>)
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>) : Task
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, continuationOptions: TaskContinuationOptions) : Task<'TResult>
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, scheduler: TaskScheduler) : Task<'TResult>
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, cancellationToken: CancellationToken) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>, continuationOptions: TaskContinuationOptions) : Task
Task.ContinueWith(continuationAction: Action<Task>, scheduler: TaskScheduler) : Task
Task.ContinueWith(continuationAction: Action<Task>, cancellationToken: CancellationToken) : Task
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, cancellationToken: CancellationToken, continuationOptions: TaskContinuationOptions, scheduler: TaskScheduler) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>, cancellationToken: CancellationToken, continuationOptions: TaskContinuationOptions, scheduler: TaskScheduler) : Task
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
type Stream =
inherit MarshalByRefObject
member BeginRead : buffer:byte[] * offset:int * count:int * callback:AsyncCallback * state:obj -> IAsyncResult
member BeginWrite : buffer:byte[] * offset:int * count:int * callback:AsyncCallback * state:obj -> IAsyncResult
member CanRead : bool
member CanSeek : bool
member CanTimeout : bool
member CanWrite : bool
member Close : unit -> unit
member CopyTo : destination:Stream -> unit + 1 overload
member Dispose : unit -> unit
member EndRead : asyncResult:IAsyncResult -> int
...
Full name: System.IO.Stream
val s : Stream
member Stream.AsyncWriteBytes : bytes:byte [] -> Async<unit>
Full name: Nessos.Vagrant.Tests.TcpActor.AsyncWriteBytes
val bytes : byte []
Multiple items
val byte : value:'T -> byte (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.byte
--------------------
type byte = Byte
Full name: Microsoft.FSharp.Core.byte
val async : AsyncBuilder
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
type BitConverter =
static val IsLittleEndian : bool
static member DoubleToInt64Bits : value:float -> int64
static member GetBytes : value:bool -> byte[] + 9 overloads
static member Int64BitsToDouble : value:int64 -> float
static member ToBoolean : value:byte[] * startIndex:int -> bool
static member ToChar : value:byte[] * startIndex:int -> char
static member ToDouble : value:byte[] * startIndex:int -> float
static member ToInt16 : value:byte[] * startIndex:int -> int16
static member ToInt32 : value:byte[] * startIndex:int -> int
static member ToInt64 : value:byte[] * startIndex:int -> int64
...
Full name: System.BitConverter
BitConverter.GetBytes(value: float) : byte []
BitConverter.GetBytes(value: float32) : byte []
BitConverter.GetBytes(value: uint64) : byte []
BitConverter.GetBytes(value: uint32) : byte []
BitConverter.GetBytes(value: uint16) : byte []
BitConverter.GetBytes(value: int64) : byte []
BitConverter.GetBytes(value: int) : byte []
BitConverter.GetBytes(value: int16) : byte []
BitConverter.GetBytes(value: char) : byte []
BitConverter.GetBytes(value: bool) : byte []
property Array.Length: int
member Stream.AsyncReadBytes : length:int -> Async<byte []>
Full name: Nessos.Vagrant.Tests.TcpActor.AsyncReadBytes
val length : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val readSegment : ('a -> int -> int -> Async<unit>)
val buf : 'a
val offset : int
val remaining : int
val read : int
type Array =
member Clone : unit -> obj
member CopyTo : array:Array * index:int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
member GetLength : dimension:int -> int
member GetLongLength : dimension:int -> int64
member GetLowerBound : dimension:int -> int
member GetUpperBound : dimension:int -> int
member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
member Initialize : unit -> unit
member IsFixedSize : bool
...
Full name: System.Array
val zeroCreate : count:int -> 'T []
Full name: Microsoft.FSharp.Collections.Array.zeroCreate
member Stream.AsyncReadBytes : unit -> Async<byte []>
Full name: Nessos.Vagrant.Tests.TcpActor.AsyncReadBytes
val lengthArr : byte []
member Stream.AsyncReadBytes : unit -> Async<byte []>
member Stream.AsyncReadBytes : length:int -> Async<byte []>
BitConverter.ToInt32(value: byte [], startIndex: int) : int
type private IReplyChannelContainer<'T> =
interface
abstract member PostWithReply : MailboxProcessor<'T> -> Async<obj>
end
Full name: Nessos.Vagrant.Tests.TcpActor.IReplyChannelContainer<_>
abstract member private IReplyChannelContainer.PostWithReply : MailboxProcessor<'T> -> Async<obj>
Full name: Nessos.Vagrant.Tests.TcpActor.IReplyChannelContainer`1.PostWithReply
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:CancellationToken -> MailboxProcessor<'Msg>
type obj = Object
Full name: Microsoft.FSharp.Core.obj
Multiple items
type private ReplyChannelContainer<'T,'R> =
interface IReplyChannelContainer<'T>
new : msgB:(AsyncReplyChannel<'R> -> 'T) -> ReplyChannelContainer<'T,'R>
Full name: Nessos.Vagrant.Tests.TcpActor.ReplyChannelContainer<_,_>
--------------------
private new : msgB:(AsyncReplyChannel<'R> -> 'T) -> ReplyChannelContainer<'T,'R>
val msgB : (AsyncReplyChannel<'R> -> 'T)
type AsyncReplyChannel<'Reply>
member Reply : value:'Reply -> unit
Full name: Microsoft.FSharp.Control.AsyncReplyChannel<_>
override private ReplyChannelContainer.PostWithReply : mb:MailboxProcessor<'T> -> Async<obj>
Full name: Nessos.Vagrant.Tests.TcpActor.ReplyChannelContainer`2.PostWithReply
val mb : MailboxProcessor<'T>
val r : 'R
member MailboxProcessor.PostAndAsyncReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> Async<'Reply>
type private ServerRequest<'T> =
| Post of 'T
| PostWithReply of IReplyChannelContainer<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.ServerRequest<_>
union case ServerRequest.Post: 'T -> ServerRequest<'T>
union case ServerRequest.PostWithReply: IReplyChannelContainer<'T> -> ServerRequest<'T>
type private ServerResponse =
| Acknowledge
| Reply of obj
| Fault of exn
Full name: Nessos.Vagrant.Tests.TcpActor.ServerResponse
union case ServerResponse.Acknowledge: ServerResponse
union case ServerResponse.Reply: obj -> ServerResponse
union case ServerResponse.Fault: exn -> ServerResponse
type exn = Exception
Full name: Microsoft.FSharp.Core.exn
Multiple items
type TcpActor<'T> =
new : mailbox:MailboxProcessor<'T> * endpoint:IPEndPoint * ?pickler:FsPickler -> TcpActor<'T>
member GetTcpClient : unit -> TcpActorClient<'T>
member Stop : unit -> unit
member MailboxProcessor : MailboxProcessor<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor<_>
--------------------
new : mailbox:MailboxProcessor<'T> * endpoint:IPEndPoint * ?pickler:FsPickler -> TcpActor<'T>
val mailbox : MailboxProcessor<'T>
val endpoint : IPEndPoint
Multiple items
type IPEndPoint =
inherit EndPoint
new : address:int64 * port:int -> IPEndPoint + 1 overload
member Address : IPAddress with get, set
member AddressFamily : AddressFamily
member Create : socketAddress:SocketAddress -> EndPoint
member Equals : comparand:obj -> bool
member GetHashCode : unit -> int
member Port : int with get, set
member Serialize : unit -> SocketAddress
member ToString : unit -> string
static val MinPort : int
...
Full name: System.Net.IPEndPoint
--------------------
IPEndPoint(address: int64, port: int) : unit
IPEndPoint(address: IPAddress, port: int) : unit
val pickler : FsPickler option
type FsPickler =
private new : unit -> FsPickler
static member Clone : value:'T * ?pickler:Pickler<'T> * ?streamingContext:StreamingContext -> 'T
static member ComputeHash : value:'T * ?hashFactory:IHashStreamFactory -> HashResult
static member ComputeSize : value:'T * ?pickler:Pickler<'T> -> int64
static member CreateBinarySerializer : ?forceLittleEndian:bool * ?typeConverter:ITypeNameConverter -> BinarySerializer
static member CreateObjectSizeCounter : ?encoding:Encoding * ?resetInterval:int64 -> ObjectSizeCounter
static member CreateXmlSerializer : ?typeConverter:ITypeNameConverter * ?indent:bool -> XmlSerializer
static member DeclareSerializable : unit -> unit
static member DeclareSerializable : t:Type -> unit
static member EnsureSerializable : graph:'T * ?failOnCloneableOnlyTypes:bool -> unit
...
Full name: Nessos.FsPickler.FsPickler
val pickler : FsPickler
union case Option.None: Option<'T>
union case Option.Some: Value: 'T -> Option<'T>
val p : FsPickler
val listener : TcpListener
Multiple items
type TcpListener =
new : localEP:IPEndPoint -> TcpListener + 2 overloads
member AcceptSocket : unit -> Socket
member AcceptTcpClient : unit -> TcpClient
member AllowNatTraversal : allowed:bool -> unit
member BeginAcceptSocket : callback:AsyncCallback * state:obj -> IAsyncResult
member BeginAcceptTcpClient : callback:AsyncCallback * state:obj -> IAsyncResult
member EndAcceptSocket : asyncResult:IAsyncResult -> Socket
member EndAcceptTcpClient : asyncResult:IAsyncResult -> TcpClient
member ExclusiveAddressUse : bool with get, set
member LocalEndpoint : EndPoint
...
Full name: System.Net.Sockets.TcpListener
--------------------
TcpListener(localEP: IPEndPoint) : unit
TcpListener(localaddr: IPAddress, port: int) : unit
val serverLoop : (unit -> Async<'a>)
val client : TcpClient
Multiple items
type TcpClient =
new : unit -> TcpClient + 3 overloads
member Available : int
member BeginConnect : host:string * port:int * requestCallback:AsyncCallback * state:obj -> IAsyncResult + 2 overloads
member Client : Socket with get, set
member Close : unit -> unit
member Connect : remoteEP:IPEndPoint -> unit + 3 overloads
member Connected : bool
member EndConnect : asyncResult:IAsyncResult -> unit
member ExclusiveAddressUse : bool with get, set
member GetStream : unit -> NetworkStream
...
Full name: System.Net.Sockets.TcpClient
--------------------
TcpClient() : unit
TcpClient(localEP: IPEndPoint) : unit
TcpClient(family: AddressFamily) : unit
TcpClient(hostname: string, port: int) : unit
val stream : NetworkStream
TcpClient.GetStream() : NetworkStream
val response : ServerResponse
val request : ServerRequest<'T>
val msg : 'T
member MailboxProcessor.Post : message:'Msg -> unit
val rcc : IReplyChannelContainer<'T>
val reply : obj
abstract member private IReplyChannelContainer.PostWithReply : MailboxProcessor<'T> -> Async<obj>
val e : exn
Multiple items
type Pickle<'T> =
new : bytes:byte [] -> Pickle<'T>
val mutable private bytes: byte []
member Bytes : byte []
Full name: Nessos.FsPickler.ExtensionMethods.Pickle<_>
--------------------
new : bytes:byte [] -> Pickle<'T>
member Stream.AsyncWriteBytes : bytes:byte [] -> Async<unit>
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val cts : CancellationTokenSource
Multiple items
type CancellationTokenSource =
new : unit -> CancellationTokenSource
member Cancel : unit -> unit + 1 overload
member Dispose : unit -> unit
member IsCancellationRequested : bool
member Token : CancellationToken
static member CreateLinkedTokenSource : [<ParamArray>] tokens:CancellationToken[] -> CancellationTokenSource + 1 overload
Full name: System.Threading.CancellationTokenSource
--------------------
CancellationTokenSource() : unit
TcpListener.Start() : unit
TcpListener.Start(backlog: int) : unit
static member Async.Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
property CancellationTokenSource.Token: CancellationToken
member TcpActor.Stop : unit -> unit
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor`1.Stop
CancellationTokenSource.Cancel() : unit
CancellationTokenSource.Cancel(throwOnFirstException: bool) : unit
TcpListener.Stop() : unit
val __ : TcpActor<'T>
Multiple items
member TcpActor.MailboxProcessor : MailboxProcessor<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor`1.MailboxProcessor
--------------------
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:CancellationToken -> MailboxProcessor<'Msg>
member TcpActor.GetTcpClient : unit -> TcpActorClient<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor`1.GetTcpClient
Multiple items
type TcpActorClient<'T> =
new : serverEndpoint:IPEndPoint * ?pickler:FsPickler -> TcpActorClient<'T>
member Post : msg:'T -> unit
member PostAndReply : msgB:(AsyncReplyChannel<'a> -> 'T) -> 'a
member PostAndReplyAsync : msgB:(AsyncReplyChannel<'R> -> 'T) -> Async<'R>
member PostAsync : msg:'T -> Async<unit>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActorClient<_>
--------------------
new : serverEndpoint:IPEndPoint * ?pickler:FsPickler -> TcpActorClient<'T>
val serverEndpoint : IPEndPoint
val sendRequest : (ServerRequest<'T> -> Async<'a>)
property IPEndPoint.Address: IPAddress
property IPEndPoint.Port: int
val reply : byte []
member TcpActorClient.PostAsync : msg:'T -> Async<unit>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActorClient`1.PostAsync
val o : obj
val failwithf : format:Printf.StringFormat<'T,'Result> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.failwithf
val raise : exn:Exception -> 'T
Full name: Microsoft.FSharp.Core.Operators.raise
val __ : TcpActorClient<'T>
member TcpActorClient.PostAndReplyAsync : msgB:(AsyncReplyChannel<'R> -> 'T) -> Async<'R>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActorClient`1.PostAndReplyAsync
val wrapper : ReplyChannelContainer<'T,'R>
val failwith : message:string -> 'T
Full name: Microsoft.FSharp.Core.Operators.failwith
member TcpActorClient.Post : msg:'T -> unit
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActorClient`1.Post
member TcpActorClient.PostAsync : msg:'T -> Async<unit>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
member TcpActorClient.PostAndReply : msgB:(AsyncReplyChannel<'a> -> 'T) -> 'a
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActorClient`1.PostAndReply
val msgB : (AsyncReplyChannel<'a> -> 'T)
member TcpActorClient.PostAndReplyAsync : msgB:(AsyncReplyChannel<'R> -> 'T) -> Async<'R>
Multiple items
type TcpActor =
private new : unit -> TcpActor
static member Connect : serverEndPoint:IPEndPoint * ?pickler:FsPickler -> TcpActorClient<'T>
static member Connect : serverEndPoint:string * ?pickler:FsPickler -> TcpActorClient<'T>
static member Create : behaviour:(MailboxProcessor<'T> -> Async<unit>) * ipEndPoint:IPEndPoint * ?pickler:FsPickler -> TcpActor<'T>
static member Create : behaviour:(MailboxProcessor<'T> -> Async<unit>) * ipEndPoint:string * ?pickler:FsPickler -> TcpActor<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor
--------------------
type TcpActor<'T> =
new : mailbox:MailboxProcessor<'T> * endpoint:IPEndPoint * ?pickler:FsPickler -> TcpActor<'T>
member GetTcpClient : unit -> TcpActorClient<'T>
member Stop : unit -> unit
member MailboxProcessor : MailboxProcessor<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor<_>
--------------------
private new : unit -> TcpActor
--------------------
new : mailbox:MailboxProcessor<'T> * endpoint:IPEndPoint * ?pickler:FsPickler -> TcpActor<'T>
val parseEndpoint : (string -> IPEndPoint)
val endpoint : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
val tokens : string []
String.Split([<ParamArray>] separator: char []) : string []
String.Split(separator: string [], options: StringSplitOptions) : string []
String.Split(separator: char [], options: StringSplitOptions) : string []
String.Split(separator: char [], count: int) : string []
String.Split(separator: string [], count: int, options: StringSplitOptions) : string []
String.Split(separator: char [], count: int, options: StringSplitOptions) : string []
Multiple items
type FormatException =
inherit SystemException
new : unit -> FormatException + 2 overloads
Full name: System.FormatException
--------------------
FormatException() : unit
FormatException(message: string) : unit
FormatException(message: string, innerException: exn) : unit
val ipAddr : IPAddress
type Dns =
static member BeginGetHostAddresses : hostNameOrAddress:string * requestCallback:AsyncCallback * state:obj -> IAsyncResult
static member BeginGetHostByName : hostName:string * requestCallback:AsyncCallback * stateObject:obj -> IAsyncResult
static member BeginGetHostEntry : hostNameOrAddress:string * requestCallback:AsyncCallback * stateObject:obj -> IAsyncResult + 1 overload
static member BeginResolve : hostName:string * requestCallback:AsyncCallback * stateObject:obj -> IAsyncResult
static member EndGetHostAddresses : asyncResult:IAsyncResult -> IPAddress[]
static member EndGetHostByName : asyncResult:IAsyncResult -> IPHostEntry
static member EndGetHostEntry : asyncResult:IAsyncResult -> IPHostEntry
static member EndResolve : asyncResult:IAsyncResult -> IPHostEntry
static member GetHostAddresses : hostNameOrAddress:string -> IPAddress[]
static member GetHostByAddress : address:string -> IPHostEntry + 1 overload
...
Full name: System.Net.Dns
Dns.GetHostAddresses(hostNameOrAddress: string) : IPAddress []
val port : int
static member TcpActor.Create : behaviour:(MailboxProcessor<'T> -> Async<unit>) * ipEndPoint:IPEndPoint * ?pickler:FsPickler -> TcpActor<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor.Create
val behaviour : (MailboxProcessor<'T> -> Async<unit>)
val ipEndPoint : IPEndPoint
static member MailboxProcessor.Start : body:(MailboxProcessor<'Msg> -> Async<unit>) * ?cancellationToken:CancellationToken -> MailboxProcessor<'Msg>
static member TcpActor.Create : behaviour:(MailboxProcessor<'T> -> Async<unit>) * ipEndPoint:string * ?pickler:FsPickler -> TcpActor<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor.Create
val ipEndPoint : string
static member TcpActor.Create : behaviour:(MailboxProcessor<'T> -> Async<unit>) * ipEndPoint:IPEndPoint * ?pickler:FsPickler -> TcpActor<'T>
static member TcpActor.Create : behaviour:(MailboxProcessor<'T> -> Async<unit>) * ipEndPoint:string * ?pickler:FsPickler -> TcpActor<'T>
static member TcpActor.Connect : serverEndPoint:IPEndPoint * ?pickler:FsPickler -> TcpActorClient<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor.Connect
val serverEndPoint : IPEndPoint
static member TcpActor.Connect : serverEndPoint:string * ?pickler:FsPickler -> TcpActorClient<'T>
Full name: Nessos.Vagrant.Tests.TcpActor.TcpActor.Connect
val serverEndPoint : string
More information