From addfa01b848870e9d9ba35aa9db9d2cfce1d3d3a Mon Sep 17 00:00:00 2001 From: Ruben Bartelink Date: Fri, 4 Mar 2022 16:01:19 +0000 Subject: [PATCH] Rename TransactAsync -> Transact --- CHANGELOG.md | 4 ++++ DOCUMENTATION.md | 13 +++++++------ samples/Store/Domain/Cart.fs | 16 ++++++++-------- samples/Store/Domain/SavedForLater.fs | 2 +- src/Equinox/Decider.fs | 6 +++--- .../AccessStrategies.fs | 2 +- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 384f2c9cd..e5e68fea3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,13 @@ The `Unreleased` section name is replaced by the expected version of next releas ## [Unreleased] ### Added + +- `Equinox`: `Decider.Transact(interpret : 'state -> Async<'event list>)` [#308](https://github.com/jet/equinox/pull/308) + ### Changed - `eqx`/`Equinox.Tool`: Flip `-P` option to opt _in_ to pretty printing [#313](https://github.com/jet/equinox/pull/313) +- `Equinox`: rename `Decider.TransactAsync` to `Transact` [#308](https://github.com/jet/equinox/pull/308) - `CosmosStore`: Require `Microsoft.Azure.Cosmos` v `3.0.25` [#310](https://github.com/jet/equinox/pull/310) - `CosmosStore`: Switch to natively using `JsonElement` event bodies [#305](https://github.com/jet/equinox/pull/305) :pray: [@ylibrach](https://github.com/ylibrach) - `CosmosStore`: Switch to natively using `System.Text.Json` for serialization of all `Microsoft.Azure.Cosmos` round-trips [#305](https://github.com/jet/equinox/pull/305) :pray: [@ylibrach](https://github.com/ylibrach) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 831fb07eb..74911eea6 100755 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -1326,7 +1326,7 @@ type Service internal (resolve : CartId -> Equinox.Decider = let decider = resolve (cartId,if optimistic then Some Equinox.AllowStale else None) - decider.TransactAsync(fun state -> async { + decider.Transact(fun state -> async { match prepare with None -> () | Some prep -> do! prep return interpretMany Fold.fold (Seq.map interpret commands) state }) ``` @@ -1368,7 +1368,7 @@ type Accumulator<'event, 'state>(fold : 'state -> 'event seq -> 'state, originSt interpret __.State |> accumulated.AddRange /// Invoke an Async decision function, gathering the events (if any) that /// it decides are necessary into the `Accumulated` sequence - member _.TransactAsync(interpret : 'state -> Async<'event list>) : Async = async { + member _.Transact(interpret : 'state -> Async<'event list>) : Async = async { let! events = interpret __.State accumulated.AddRange events } /// Invoke a decision function, while also propagating a result yielded as @@ -1379,21 +1379,22 @@ type Accumulator<'event, 'state>(fold : 'state -> 'event seq -> 'state, originSt result /// Invoke a decision function, while also propagating a result yielded as /// the fst of an (result, events) pair - member _.TransactAsync(decide : 'state -> Async<'result * 'event list>) : Async<'result> = async { + member _.Transact(decide : 'state -> Async<'result * 'event list>) : Async<'result> = async { let! result, newEvents = decide __.State accumulated.AddRange newEvents return result } type Service ... = member _.Run(cartId, optimistic, commands : Command seq, ?prepare) : Async = - let decider = resolve (cartId,if optimistic then Some Equinox.AllowStale else None) - decider.TransactAsync(fun state -> async { + let decider = resolve cartId + let opt = if optimistic then Some Equinox.AllowStale else Equinox.RequireLoad + decider.Transact(fun state -> async { match prepare with None -> () | Some prep -> do! prep let acc = Accumulator(Fold.fold, state) for cmd in commands do acc.Transact(interpret cmd) return acc.State, acc.Accumulated - }) + }, opt) ``` # Equinox Architectural Overview diff --git a/samples/Store/Domain/Cart.fs b/samples/Store/Domain/Cart.fs index da2a13fda..71fde7815 100644 --- a/samples/Store/Domain/Cart.fs +++ b/samples/Store/Domain/Cart.fs @@ -101,27 +101,27 @@ type Accumulator<'event, 'state>(fold : 'state -> 'event seq -> 'state, originSt let accumulated = ResizeArray<'event>() /// The Events that have thus far been pended via the `decide` functions `Execute`/`Decide`d during the course of this flow - member __.Accumulated : 'event list = + member _.Accumulated : 'event list = accumulated |> List.ofSeq /// The current folded State, based on the Stream's `originState` + any events that have been Accumulated during the the decision flow - member __.State : 'state = + member _.State : 'state = accumulated |> fold originState /// Invoke a decision function, gathering the events (if any) that it decides are necessary into the `Accumulated` sequence - member __.Transact(interpret : 'state -> 'event list) : unit = + member _.Transact(interpret : 'state -> 'event list) : unit = interpret __.State |> accumulated.AddRange /// Invoke an Async decision function, gathering the events (if any) that it decides are necessary into the `Accumulated` sequence - member __.TransactAsync(interpret : 'state -> Async<'event list>) : Async = async { + member _.Transact(interpret : 'state -> Async<'event list>) : Async = async { let! events = interpret __.State accumulated.AddRange events } /// Invoke a decision function, while also propagating a result yielded as the fst of an (result, events) pair - member __.Transact(decide : 'state -> 'result * 'event list) : 'result = + member _.Transact(decide : 'state -> 'result * 'event list) : 'result = let result, newEvents = decide __.State accumulated.AddRange newEvents result /// Invoke a decision function, while also propagating a result yielded as the fst of an (result, events) pair - member __.TransactAsync(decide : 'state -> Async<'result * 'event list>) : Async<'result> = async { + member _.Transact(decide : 'state -> Async<'result * 'event list>) : Async<'result> = async { let! result, newEvents = decide __.State accumulated.AddRange newEvents return result } @@ -138,13 +138,13 @@ type Service internal (resolve : CartId * Equinox.ResolveOption option -> Equino member __.Run(cartId, optimistic, commands : Command seq, ?prepare) : Async = let decider = resolve (cartId,if optimistic then Some Equinox.AllowStale else None) - decider.TransactAsync(fun state -> async { + decider.Transact(fun state -> async { match prepare with None -> () | Some prep -> do! prep #if ACCUMULATOR let acc = Accumulator(Fold.fold, state) for cmd in commands do acc.Transact(interpret cmd) - return acc.State, acc.Accumulated }) + return acc.State, acc.Accumulated } #else return interpretMany Fold.fold (Seq.map interpret commands) state }) #endif diff --git a/samples/Store/Domain/SavedForLater.fs b/samples/Store/Domain/SavedForLater.fs index c0e19c90e..338f85db9 100644 --- a/samples/Store/Domain/SavedForLater.fs +++ b/samples/Store/Domain/SavedForLater.fs @@ -119,7 +119,7 @@ type Service internal (resolve : ClientId -> Equinox.Deciderbool) -> Async)) : Async = let decider = resolve clientId - decider.TransactAsync(fun (state : Fold.State) -> async { + decider.Transact(fun (state : Fold.State) -> async { let contents = seq { for item in state -> item.skuId } |> set let! cmd = resolveCommand contents.Contains let _, events = decide maxSavedItems cmd state diff --git a/src/Equinox/Decider.fs b/src/Equinox/Decider.fs index 2295e0b5f..0918e0387 100755 --- a/src/Equinox/Decider.fs +++ b/src/Equinox/Decider.fs @@ -45,14 +45,14 @@ type Decider<'event, 'state> /// 1a. (if events yielded) Attempt to sync the yielded events events to the stream /// 1b. Tries up to maxAttempts times in the case of a conflict, throwing MaxResyncsExhaustedException to signal failure. /// 2. Yield result - member _.TransactAsync(decide : 'state -> Async<'result * 'event list>) : Async<'result> = + member _.Transact(decide : 'state -> Async<'result * 'event list>) : Async<'result> = transact (fun context -> decide context.State) (fun result _context -> result) /// 0. Invoke the supplied _Async_ decide function with the present state (including extended context), holding the 'result /// 1a. (if events yielded) Attempt to sync the yielded events events to the stream /// 1b. Tries up to maxAttempts times in the case of a conflict, throwing MaxResyncsExhaustedException to signal failure. - /// 2. Uses mapResult to render the final outcome from the 'result and/or the final ISyncContext - /// 3. Yields the outcome + /// 2. Uses mapResult to render the final 'view from the 'result and/or the final ISyncContext + /// 3. Yields the 'view member _.TransactEx(decide : ISyncContext<'state> -> Async<'result * 'event list>, mapResult : 'result -> ISyncContext<'state> -> 'view) : Async<'view> = transact decide mapResult diff --git a/tests/Equinox.CosmosStore.Integration/AccessStrategies.fs b/tests/Equinox.CosmosStore.Integration/AccessStrategies.fs index edf925529..274f36b00 100644 --- a/tests/Equinox.CosmosStore.Integration/AccessStrategies.fs +++ b/tests/Equinox.CosmosStore.Integration/AccessStrategies.fs @@ -56,7 +56,7 @@ module SequenceCheck = member _.Add(instance : Guid, value : int, count) : Async = let decider = resolve instance - decider.TransactEx((fun c -> async { return (), decide (value, count) c.State }), (fun () c -> c.State)) + decider.TransactEx((fun c -> async { return (), decide (value, count) c.State }), fun () c -> c.State) let private create log resolveStream = let resolve = streamName >> resolveStream >> (createDecider log)