Header menu logo FCQRS

Running the example

Above code is where we Bootstrap the read side and aquire some handle to subscribe to the events. Last known offset is the last event that was processed. Here for demo purposes, we are using 0L. In production, you should get the last known offset from the database or persistent storage.

let lastKnownOffset = 0L
let sub = Bootstrap.sub Query.handleEventWrapper lastKnownOffset

Then we create a function to generate a correlation id. This is used to track the command. We will explain ValueLens later. For now, just know that it is a way to create a value from a function.

let cid (): CID =
    System.Guid.NewGuid().ToString() |> ValueLens.CreateAsResult |> Result.value

// user name and password for testing.
let userName = "testuser"

let password = "password"

let cid1 = cid()

We create a subscription BEFORE sending the command. This is to ensure that we don't miss the event. We are interested in the first event that has the same CID as the one we are sending.

let s = sub.Subscribe((fun e -> e.CID = cid1), 1)

Send the command to register a new user. You can also use async block here

let result = register cid1 userName password |> Async.RunSynchronously

Wait for the event to happen. Means read-side is completed

(s |> Async.RunSynchronously).Dispose()
printfn "%A" result
namespace FCQRS
namespace FCQRS.Model
module Data from FCQRS.Model
module Command
val lastKnownOffset: int64
val sub: FCQRS.Query.ISubscribe<IMessageWithCID>
module Bootstrap
val sub: handleEventWrapper: (Environments.AppEnv -> int64 -> obj -> 'a list) -> offsetCount: int64 -> FCQRS.Query.ISubscribe<'a>
module Query
val handleEventWrapper: env: FCQRS.Common.ILoggerFactoryWrapper -> offsetValue: int64 -> event: obj -> IMessageWithCID list
val cid: unit -> CID
type CID = private | CID of ShortString member Equals: CID * IEqualityComparer -> bool override ToString: unit -> string member IsValid: bool static member Value_: (CID -> ShortString) * (ShortString -> CID -> CID)
<summary> CorrelationID for commands and Sagas </summary>
namespace System
Multiple items
[<Struct>] type Guid = new: b: byte array -> unit + 6 overloads member CompareTo: value: Guid -> int + 1 overload member Equals: g: Guid -> bool + 1 overload member GetHashCode: unit -> int member ToByteArray: unit -> byte array + 1 overload member ToString: unit -> string + 2 overloads member TryFormat: utf8Destination: Span<byte> * bytesWritten: byref<int> * ?format: ReadOnlySpan<char> -> bool + 1 overload member TryWriteBytes: destination: Span<byte> -> bool + 1 overload static member (<) : left: Guid * right: Guid -> bool static member (<=) : left: Guid * right: Guid -> bool ...
<summary>Represents a globally unique identifier (GUID).</summary>

--------------------
System.Guid ()
System.Guid(b: byte array) : System.Guid
System.Guid(b: System.ReadOnlySpan<byte>) : System.Guid
System.Guid(g: string) : System.Guid
System.Guid(b: System.ReadOnlySpan<byte>, bigEndian: bool) : System.Guid
System.Guid(a: int, b: int16, c: int16, d: byte array) : System.Guid
System.Guid(a: int, b: int16, c: int16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : System.Guid
System.Guid(a: uint32, b: uint16, c: uint16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : System.Guid
System.Guid.NewGuid() : System.Guid
type ValueLens = static member Create: innerValue: 'Inner -> 'Wrapped (requires member Value_) static member CreateAsResult: v: 'a -> Result<'b,'d> (requires member Value_ and member Value_) static member IsValidValue: this: 'Wrapped -> bool (requires member Value_) static member Isvalid: this: 'a -> bool (requires member Value_ and member Value_) static member ToString: this: 'Wrapped -> string (requires member Value_) static member TryCreate: innerValue: 'Inner -> Result<'Wrapped,'Error> (requires member Value_) static member Value: this: 'Wrapped -> 'Inner (requires member Value_) + 1 overload
static member ValueLens.CreateAsResult: v: 'a -> Result<'b,'d> (requires member Value_ and member Value_)
Multiple items
module Result from FCQRS.Model.Data

--------------------
module Result from Microsoft.FSharp.Core

--------------------
[<Struct>] type Result<'T,'TError> = | Ok of ResultValue: 'T | Error of ErrorValue: 'TError
val value: e: Result<'a,'b> -> 'a
val userName: string
val password: string
val cid1: CID
val s: FCQRS.Query.IAwaitableDisposable
abstract FCQRS.Query.ISubscribe.Subscribe: callback: ('TDataEvent -> unit) * ?cancellationToken: System.Threading.CancellationToken -> System.IDisposable
abstract FCQRS.Query.ISubscribe.Subscribe: filter: ('TDataEvent -> bool) * take: int * ?callback: ('TDataEvent -> unit) * ?cancellationToken: System.Threading.CancellationToken -> FCQRS.Query.IAwaitableDisposable
val e: IMessageWithCID
property IMessageWithCID.CID: CID with get
<summary> Gets the Correlation ID associated with the message. </summary>
val result: Result<Version,string list>
val register: cid: CID -> userName: string -> password: string -> Async<Result<Version,string list>>
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> + 1 overload 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 Choice: computations: Async<'T option> seq -> Async<'T option> static member FromBeginEnd: beginAction: (AsyncCallback * obj -> IAsyncResult) * endAction: (IAsyncResult -> 'T) * ?cancelAction: (unit -> unit) -> Async<'T> + 3 overloads static member FromContinuations: callback: (('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T> ...

--------------------
type Async<'T>
static member Async.RunSynchronously: computation: Async<'T> * ?timeout: int * ?cancellationToken: System.Threading.CancellationToken -> 'T
val printfn: format: Printf.TextWriterFormat<'T> -> 'T

Type something to start searching.