You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: DOCUMENTATION.md
+35-16Lines changed: 35 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -388,43 +388,63 @@ module Fold =
388
388
389
389
module Snapshot =
390
390
391
-
let generate (state: State): Event =
391
+
let generate (state: State): Events.Event =
392
392
Events.Snapshotted { ... }
393
-
let isOrigin = function
394
-
| Events.Snapshotted -> true
395
-
| _ -> false
393
+
let isOrigin = function Events.Snapshotted -> true | _ -> false
396
394
let config = isOrigin, generate
397
-
let hydrate (e: Snapshotted): State = ...
395
+
let hydrate (e: Events.Snapshotted): State = ...
398
396
399
397
let private evolve state = function
400
398
| Events.Snapshotted e -> Snapshot.hydrate e
401
399
| Events.X -> (state update)
402
400
| Events.Y -> (state update)
403
401
let fold = Array.fold evolve
404
402
405
-
let interpretX ... (state: Fold.State): Events list = ...
403
+
module Decisions =
406
404
407
-
type Decision =
408
-
| Accepted
409
-
| Failed of Reason
405
+
let interpretX ... (state: Fold.State): Events.Event[] = ...
410
406
411
-
let decideY ... (state: Fold.State): Decision * Events list = ...
407
+
type Decision =
408
+
| Accepted
409
+
| Failed of Reason
410
+
411
+
let decideY ... (state: Fold.State): Decision * Events.Event[] = ...
412
412
```
413
413
414
414
-`interpret`, `decide`_and related input and output types / interfaces_ are
415
415
public and top-level for use in unit tests (often unit tests will `open` the
416
416
`module Fold` to use `initial` and `fold`)
417
417
418
+
In some cases, where surfacing the state in some way makes sense (it doesn't always; see [CQRS](https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs)), you'll have a:
419
+
420
+
```fsharp
421
+
module Queries =
422
+
423
+
type XzyInfo = { ... }
424
+
425
+
let renderXyz (s: State): XzyInfo =
426
+
{ ... }
427
+
```
428
+
429
+
The above functions can all be unit tested directly. All other tests should use the `Service` with a `MemoryStore` via the `member`s on that:
430
+
418
431
```fsharp
419
432
type Service internal (resolve: Id -> Equinox.Decider<Events.Event, Fold.State) = ...`
420
433
421
434
member _.Execute(id, command): Async<unit> =
422
435
let decider = resolve id
423
-
decider.Transact(interpretX command)
436
+
decider.Transact(Decisions.interpretX command)
424
437
425
438
member _.Decide(id, inputs): Async<Decision> =
426
439
let decider = resolve id
427
-
decider.Transact(decideX inputs)
440
+
decider.Transact(Decisions.decideX inputs)
441
+
442
+
member private _.Query(maxAge, render): Async<Queries.XyzInfo> =
an alternate approach is to encapsulate the folding (Equinox in V1 exposed an
1395
+
An alternate approach is to encapsulate the folding (Equinox in V1 exposed an
1378
1396
interface that encouraged such patterns; this was removed in two steps, as code
1379
1397
written using the idiomatic approach is [intrinsically simpler, even if it
1380
1398
seems not as Easy](https://www.infoq.com/presentations/Simple-Made-Easy/) at
@@ -2116,6 +2134,7 @@ Further information:
2116
2134
-[DynamoDB Transactions: Use Cases and Examples](https://www.alexdebrie.com/posts/dynamodb-transactions/) by Alex DeBrie
2117
2135
provides a thorough review of the `TransactWriteItems` facility (TL;DR: it's far more general than the stream level atomic
2118
2136
transactions afforded by CosmosDB's Stored Procedures)
2137
+
- while it doesn't provide deeper insight into the API from a usage perspective, [Distributed Transactions at Scale in Amazon DynamoDB](https://www.infoq.com/articles/amazon-dynamodb-transactions) is a great deep dive into how the facility is implemented.
0 commit comments