3 people like it.

Simple Redis F# Client Test

Simple Redis F# Client Test (Async version will stop respond when data are too large. Don't know how to solve yet.)

 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: 
open System
open System.Net.Sockets
open System.Text

type RedisClient () =

    // Socket
    let clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    do clientSocket.Connect("127.0.0.1", 6379)
    let netStream = new NetworkStream(clientSocket, true)

    // Helper
    let toS (o:obj) = Convert.ToString(o)
    let toC (o:obj) = Convert.ToChar(o)
    let getBytes (s:string) = Encoding.UTF8.GetBytes(s) 
    let getString (b:byte[]) = Encoding.UTF8.GetString(b)                                                               
    let mergeCommand (l:list<String>) = 
            let sb = new StringBuilder()
            sb.Append("*" + toS l.Length + "\r\n") |> ignore
            l |> List.iter (fun item -> sb.Append("$" + toS item.Length + "\r\n") |> ignore
                                        sb.Append(toS item + "\r\n") |> ignore )
            getBytes <| sb.ToString()            

    // Member    
    member x.AsyncSend l = async { let b = mergeCommand l
                                   do! netStream.AsyncWrite(b, 0, b.Length) }

    member x.SyncSend l = let b = mergeCommand l
                          netStream.Write(b, 0, b.Length)

    member x.ReadLine () = let n = ref 0
                           let sb = new StringBuilder()        
                           while !n <> 10 do
                             n := netStream.ReadByte()
                             if !n <> 13 && !n <> 10 then sb.Append(toC !n) |> ignore
                           sb.ToString()
                                                    
    member x.Close () = netStream.Close()

             
// Test Helper
let values m = List.concat [for i in 1 .. m -> ["K" + i.ToString(); "V" + i.ToString()] ]
               // ["K1";"V1";"K2";"V2";"K3";"V3"; ... ]

let SyncTest n v =  [ for i in 1 .. n ->
                        async {
                            let r = new RedisClient()
                            r.SyncSend("MSET" :: v)
                            let s = r.ReadLine()
                            r.Close()
                            return s                }] |> Async.Parallel |> Async.RunSynchronously

let AsyncTest n v =  [ for i in 1 .. n ->
                        async {
                            let r = new RedisClient()
                            do! r.AsyncSend("MSET" :: v)
                            let s = r.ReadLine()
                            r.Close() 
                            return s                }] |> Async.Parallel |> Async.RunSynchronously

let RealSync n v =  [ for i in 1 .. n ->
                        let r = new RedisClient()
                        r.SyncSend("MSET" :: v)
                        let s = r.ReadLine()
                        r.Close() 
                        s                       ] 
// Test
#time
let shortValues = values 100
let longValues  = values 2000
     
SyncTest  3000  shortValues 
AsyncTest 3000  shortValues 
RealSync  3000  shortValues 
 
SyncTest  3000  longValues 
AsyncTest 3000  longValues // Async version will stop respond when data are too large.
                           // Don't know how to solve yet.
RealSync  3000  longValues
namespace System
namespace System.Net
namespace System.Net.Sockets
namespace System.Text
Multiple items
type RedisClient =
  new : unit -> RedisClient
  member AsyncSend : l:String list -> Async<unit>
  member Close : unit -> unit
  member ReadLine : unit -> string
  member SyncSend : l:String list -> unit

Full name: Script.RedisClient

--------------------
new : unit -> RedisClient
val clientSocket : Socket
Multiple items
type Socket =
  new : socketInformation:SocketInformation -> Socket + 1 overload
  member Accept : unit -> Socket
  member AcceptAsync : e:SocketAsyncEventArgs -> bool
  member AddressFamily : AddressFamily
  member Available : int
  member BeginAccept : callback:AsyncCallback * state:obj -> IAsyncResult + 2 overloads
  member BeginConnect : remoteEP:EndPoint * callback:AsyncCallback * state:obj -> IAsyncResult + 3 overloads
  member BeginDisconnect : reuseSocket:bool * callback:AsyncCallback * state:obj -> IAsyncResult
  member BeginReceive : buffers:IList<ArraySegment<byte>> * socketFlags:SocketFlags * callback:AsyncCallback * state:obj -> IAsyncResult + 3 overloads
  member BeginReceiveFrom : buffer:byte[] * offset:int * size:int * socketFlags:SocketFlags * remoteEP:EndPoint * callback:AsyncCallback * state:obj -> IAsyncResult
  ...

Full name: System.Net.Sockets.Socket

--------------------
Socket(socketInformation: SocketInformation) : unit
Socket(addressFamily: AddressFamily, socketType: SocketType, protocolType: ProtocolType) : unit
type AddressFamily =
  | Unknown = -1
  | Unspecified = 0
  | Unix = 1
  | InterNetwork = 2
  | ImpLink = 3
  | Pup = 4
  | Chaos = 5
  | NS = 6
  | Ipx = 6
  | Iso = 7
  ...

Full name: System.Net.Sockets.AddressFamily
field AddressFamily.InterNetwork = 2
type SocketType =
  | Stream = 1
  | Dgram = 2
  | Raw = 3
  | Rdm = 4
  | Seqpacket = 5
  | Unknown = -1

Full name: System.Net.Sockets.SocketType
field SocketType.Stream = 1
type ProtocolType =
  | IP = 0
  | IPv6HopByHopOptions = 0
  | Icmp = 1
  | Igmp = 2
  | Ggp = 3
  | IPv4 = 4
  | Tcp = 6
  | Pup = 12
  | Udp = 17
  | Idp = 22
  ...

Full name: System.Net.Sockets.ProtocolType
field ProtocolType.Tcp = 6
Socket.Connect(remoteEP: Net.EndPoint) : unit
Socket.Connect(addresses: Net.IPAddress [], port: int) : unit
Socket.Connect(host: string, port: int) : unit
Socket.Connect(address: Net.IPAddress, port: int) : unit
val netStream : NetworkStream
Multiple items
type NetworkStream =
  inherit Stream
  new : socket:Socket -> NetworkStream + 3 overloads
  member BeginRead : buffer:byte[] * offset:int * size:int * callback:AsyncCallback * state:obj -> IAsyncResult
  member BeginWrite : buffer:byte[] * offset:int * size:int * callback:AsyncCallback * state:obj -> IAsyncResult
  member CanRead : bool
  member CanSeek : bool
  member CanTimeout : bool
  member CanWrite : bool
  member Close : timeout:int -> unit
  member DataAvailable : bool
  member EndRead : asyncResult:IAsyncResult -> int
  ...

Full name: System.Net.Sockets.NetworkStream

--------------------
NetworkStream(socket: Socket) : unit
NetworkStream(socket: Socket, ownsSocket: bool) : unit
NetworkStream(socket: Socket, access: IO.FileAccess) : unit
NetworkStream(socket: Socket, access: IO.FileAccess, ownsSocket: bool) : unit
val toS : (obj -> string)
val o : obj
type obj = Object

Full name: Microsoft.FSharp.Core.obj
type Convert =
  static val DBNull : obj
  static member ChangeType : value:obj * typeCode:TypeCode -> obj + 3 overloads
  static member FromBase64CharArray : inArray:char[] * offset:int * length:int -> byte[]
  static member FromBase64String : s:string -> byte[]
  static member GetTypeCode : value:obj -> TypeCode
  static member IsDBNull : value:obj -> bool
  static member ToBase64CharArray : inArray:byte[] * offsetIn:int * length:int * outArray:char[] * offsetOut:int -> int + 1 overload
  static member ToBase64String : inArray:byte[] -> string + 3 overloads
  static member ToBoolean : value:obj -> bool + 17 overloads
  static member ToByte : value:obj -> byte + 18 overloads
  ...

Full name: System.Convert
Convert.ToString(value: string) : string
   (+0 other overloads)
Convert.ToString(value: DateTime) : string
   (+0 other overloads)
Convert.ToString(value: decimal) : string
   (+0 other overloads)
Convert.ToString(value: float) : string
   (+0 other overloads)
Convert.ToString(value: float32) : string
   (+0 other overloads)
Convert.ToString(value: uint64) : string
   (+0 other overloads)
Convert.ToString(value: int64) : string
   (+0 other overloads)
Convert.ToString(value: uint32) : string
   (+0 other overloads)
Convert.ToString(value: int) : string
   (+0 other overloads)
Convert.ToString(value: uint16) : string
   (+0 other overloads)
val toC : (obj -> char)
Convert.ToChar(value: DateTime) : char
   (+0 other overloads)
Convert.ToChar(value: decimal) : char
   (+0 other overloads)
Convert.ToChar(value: float) : char
   (+0 other overloads)
Convert.ToChar(value: float32) : char
   (+0 other overloads)
Convert.ToChar(value: string) : char
   (+0 other overloads)
Convert.ToChar(value: uint64) : char
   (+0 other overloads)
Convert.ToChar(value: int64) : char
   (+0 other overloads)
Convert.ToChar(value: uint32) : char
   (+0 other overloads)
Convert.ToChar(value: int) : char
   (+0 other overloads)
Convert.ToChar(value: uint16) : char
   (+0 other overloads)
val getBytes : (string -> byte [])
val s : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
type Encoding =
  member BodyName : string
  member Clone : unit -> obj
  member CodePage : int
  member DecoderFallback : DecoderFallback with get, set
  member EncoderFallback : EncoderFallback with get, set
  member EncodingName : string
  member Equals : value:obj -> bool
  member GetByteCount : chars:char[] -> int + 3 overloads
  member GetBytes : chars:char[] -> byte[] + 5 overloads
  member GetCharCount : bytes:byte[] -> int + 2 overloads
  ...

Full name: System.Text.Encoding
property Encoding.UTF8: Encoding
Encoding.GetBytes(s: string) : byte []
Encoding.GetBytes(chars: char []) : byte []
Encoding.GetBytes(chars: char [], index: int, count: int) : byte []
Encoding.GetBytes(chars: nativeptr<char>, charCount: int, bytes: nativeptr<byte>, byteCount: int) : int
Encoding.GetBytes(s: string, charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
Encoding.GetBytes(chars: char [], charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
val getString : (byte [] -> string)
val b : 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
Encoding.GetString(bytes: byte []) : string
Encoding.GetString(bytes: byte [], index: int, count: int) : string
val mergeCommand : (String list -> byte [])
val l : String list
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
Multiple items
type String =
  new : value:char -> string + 7 overloads
  member Chars : int -> char
  member Clone : unit -> obj
  member CompareTo : value:obj -> int + 1 overload
  member Contains : value:string -> bool
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EndsWith : value:string -> bool + 2 overloads
  member Equals : obj:obj -> bool + 2 overloads
  member GetEnumerator : unit -> CharEnumerator
  member GetHashCode : unit -> int
  ...

Full name: System.String

--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Encoding) : unit
val sb : StringBuilder
Multiple items
type StringBuilder =
  new : unit -> StringBuilder + 5 overloads
  member Append : value:string -> StringBuilder + 18 overloads
  member AppendFormat : format:string * arg0:obj -> StringBuilder + 4 overloads
  member AppendLine : unit -> StringBuilder + 1 overload
  member Capacity : int with get, set
  member Chars : int -> char with get, set
  member Clear : unit -> StringBuilder
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EnsureCapacity : capacity:int -> int
  member Equals : sb:StringBuilder -> bool
  ...

Full name: System.Text.StringBuilder

--------------------
StringBuilder() : unit
StringBuilder(capacity: int) : unit
StringBuilder(value: string) : unit
StringBuilder(value: string, capacity: int) : unit
StringBuilder(capacity: int, maxCapacity: int) : unit
StringBuilder(value: string, startIndex: int, length: int, capacity: int) : unit
StringBuilder.Append(value: char []) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: obj) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: uint64) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: uint32) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: uint16) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: decimal) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: float) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: float32) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: int64) : StringBuilder
   (+0 other overloads)
StringBuilder.Append(value: int) : StringBuilder
   (+0 other overloads)
property List.Length: int
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val iter : action:('T -> unit) -> list:'T list -> unit

Full name: Microsoft.FSharp.Collections.List.iter
val item : String
property String.Length: int
StringBuilder.ToString() : string
StringBuilder.ToString(startIndex: int, length: int) : string
val x : RedisClient
member RedisClient.AsyncSend : l:String list -> Async<unit>

Full name: Script.RedisClient.AsyncSend
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
member IO.Stream.AsyncWrite : buffer:byte [] * ?offset:int * ?count:int -> Async<unit>
property Array.Length: int
member RedisClient.SyncSend : l:String list -> unit

Full name: Script.RedisClient.SyncSend
NetworkStream.Write(buffer: byte [], offset: int, size: int) : unit
member RedisClient.ReadLine : unit -> string

Full name: Script.RedisClient.ReadLine
val n : int ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
IO.Stream.ReadByte() : int
member RedisClient.Close : unit -> unit

Full name: Script.RedisClient.Close
IO.Stream.Close() : unit
NetworkStream.Close(timeout: int) : unit
val values : m:int -> string list

Full name: Script.values
val m : int
val concat : lists:seq<'T list> -> 'T list

Full name: Microsoft.FSharp.Collections.List.concat
val i : int
Int32.ToString() : string
Int32.ToString(provider: IFormatProvider) : string
Int32.ToString(format: string) : string
Int32.ToString(format: string, provider: IFormatProvider) : string
val SyncTest : n:int -> v:String list -> string []

Full name: Script.SyncTest
val n : int
val v : String list
val r : RedisClient
member RedisClient.SyncSend : l:String list -> unit
member RedisClient.ReadLine : unit -> string
member RedisClient.Close : unit -> unit
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<_>
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
val AsyncTest : n:int -> v:String list -> string []

Full name: Script.AsyncTest
member RedisClient.AsyncSend : l:String list -> Async<unit>
val RealSync : n:int -> v:String list -> string list

Full name: Script.RealSync
val shortValues : string list

Full name: Script.shortValues
val longValues : string list

Full name: Script.longValues
Raw view Test code New version

More information

Link:http://fssnip.net/4j
Posted:14 years ago
Author:Richard Chang
Tags: socket , redis