Skip to content

Commit

Permalink
Migrate EventBody to FsCodec 3 conventions (#323)
Browse files Browse the repository at this point in the history
  • Loading branch information
bartelink authored May 12, 2022
1 parent 1dbb49c commit a5bb269
Show file tree
Hide file tree
Showing 62 changed files with 278 additions and 280 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ The `Unreleased` section name is replaced by the expected version of next releas
### Added

- `eqx dump`/`Equinox.Tool`: Add `-F` option to opt out of pretty printing unfolds [#319](https://github.com/jet/equinox/pull/319)
- `eqx dump`/`Equinox.Tool`: Show payload statistics [#323](https://github.com/jet/equinox/pull/323)
- `eqx dump`/`Equinox.Tool`: Add `-B` option to prevent assuming UTF-8 bodies [#323](https://github.com/jet/equinox/pull/323)
- `Equinox`: `Decider.Transact(interpret : 'state -> Async<'event list>)` [#314](https://github.com/jet/equinox/pull/314)

### Changed
Expand All @@ -19,16 +21,17 @@ The `Unreleased` section name is replaced by the expected version of next releas
- `Equinox`: rename `Decider.TransactAsync` to `Transact` [#314](https://github.com/jet/equinox/pull/314)
- `Equinox`: Merge `ResolveOption` and `XXXStoreCategory.FromMemento` as `LoadOption` [#308](https://github.com/jet/equinox/pull/308)
- `Equinox`: Merge `XXXStoreCategory.Resolve(sn, ?ResolveOption)` and `XXXStoreCategory.FromMemento` as option `LoadOption` parameter on all `Transact` and `Query` methods [#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`: Require `Microsoft.Azure.Cosmos` v `3.27.0` [#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)
- `CosmosStore`: Only log `bytes` when log level is `Debug` [#305](https://github.com/jet/equinox/pull/305)
- `EventStore`: Target `EventStore.Client` v `22.0.0-preview`; rename `Connector` -> `EventStoreConnector` [#317](https://github.com/jet/equinox/pull/317)
- Update all non-Client dependencies except `FSharp.Core`, `FSharp.Control.AsyncSeq` [#310](https://github.com/jet/equinox/pull/310)
- Update all Stores to use `FsCodec` v `3.0.0`, with [`EventBody` types switching from `byte[]` to `ReadOnlyMemory<byte>`, see FsCodec#75](https://github.com/jet/FsCodec/pull/75) [#323](https://github.com/jet/equinox/pull/323)

### Removed

- Remove explicit `net461` handling; minimum target now `netstandard 2.1` / `net6.0` [#310](https://github.com/jet/equinox/pull/310)
- Remove explicit `net461` handling; minimum target now `netstandard 2.1` / `net6.0` / `FSharp.Core` v `4.5.4` [#310](https://github.com/jet/equinox/pull/310) [#323](https://github.com/jet/equinox/pull/323)

### Fixed

Expand Down
2 changes: 2 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
<PackageLicense>Apache-2.0</PackageLicense>
<Copyright>Copyright © 2016-22</Copyright>

<WarningLevel>5</WarningLevel>

<ThisDirAbsolute>$([System.IO.Path]::GetFullPath("$(MSBuildThisFileDirectory)"))</ThisDirAbsolute>

<!-- SourceLink related properties https://github.com/dotnet/SourceLink#using-sourcelink -->
Expand Down
4 changes: 1 addition & 3 deletions samples/Infrastructure/Infrastructure.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<WarningLevel>5</WarningLevel>
<IsTestProject>false</IsTestProject>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
<DisableImplicitSystemValueTupleReference>true</DisableImplicitSystemValueTupleReference>
</PropertyGroup>
Expand All @@ -27,7 +25,7 @@
<ItemGroup>
<PackageReference Include="Argu" Version="6.1.1" />
<PackageReference Include="Destructurama.FSharp" Version="1.2.0" />
<PackageReference Include="FSharp.Core" Version="4.3.4" />
<PackageReference Include="FSharp.Core" Version="4.5.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="5.1.1" />
Expand Down
4 changes: 2 additions & 2 deletions samples/Infrastructure/Services.fs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
module Samples.Infrastructure.Services

open Domain
open FsCodec.SystemTextJson
open FsCodec.SystemTextJson.Interop // use ToJsonElementCodec because we are doing an overkill example
open Microsoft.Extensions.DependencyInjection
open System

type StreamResolver(storage) =
member _.Resolve
( codec : FsCodec.IEventCodec<'event,byte[],_>,
( codec : FsCodec.IEventCodec<'event, ReadOnlyMemory<byte>, _>,
fold: 'state -> 'event seq -> 'state,
initial : 'state,
snapshot : ('event -> bool) * ('state -> 'event)) =
Expand Down
2 changes: 1 addition & 1 deletion samples/Infrastructure/Storage.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ open System
[<RequireQualifiedAccess; NoEquality; NoComparison>]
type StorageConfig =
// For MemoryStore, we keep the events as UTF8 arrays - we could use FsCodec.Codec.Box to remove the JSON encoding, which would improve perf but can conceal problems
| Memory of Equinox.MemoryStore.VolatileStore<byte[]>
| Memory of Equinox.MemoryStore.VolatileStore<ReadOnlyMemory<byte>>
| Cosmos of Equinox.CosmosStore.CosmosStoreContext * Equinox.CosmosStore.CachingStrategy * unfolds: bool
| Es of Equinox.EventStore.EventStoreContext * Equinox.EventStore.CachingStrategy option * unfolds: bool
| Sql of Equinox.SqlStreamStore.SqlStreamStoreContext * Equinox.SqlStreamStore.CachingStrategy option * unfolds: bool
Expand Down
2 changes: 0 additions & 2 deletions samples/Store/Domain.Tests/Domain.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<WarningLevel>5</WarningLevel>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions samples/Store/Domain/Cart.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ module Events =
| ItemQuantityChanged of ItemQuantityChangedInfo
| ItemPropertiesChanged of ItemPropertiesChangedInfo
interface TypeShape.UnionContract.IUnionContract
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codecStj = FsCodec.SystemTextJson.Codec.Create<Event>()
let codec = EventCodec.create<Event>()
let codecJe = EventCodec.createJson<Event>()

module Fold =

Expand Down
4 changes: 2 additions & 2 deletions samples/Store/Domain/ContactPreferences.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ module Events =
type Event =
| [<System.Runtime.Serialization.DataMember(Name = "contactPreferencesChanged")>]Updated of Value
interface TypeShape.UnionContract.IUnionContract
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codecStj = FsCodec.SystemTextJson.Codec.Create<Event>()
let codec = EventCodec.create<Event>()
let codecJe = EventCodec.createJson<Event>()

module Fold =

Expand Down
8 changes: 3 additions & 5 deletions samples/Store/Domain/Domain.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<WarningLevel>5</WarningLevel>
<IsTestProject>false</IsTestProject>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
<DisableImplicitSystemValueTupleReference>true</DisableImplicitSystemValueTupleReference>
</PropertyGroup>
Expand All @@ -19,10 +17,10 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="FSharp.Core" Version="4.3.4" />
<PackageReference Include="FSharp.Core" Version="4.5.4" />

<PackageReference Include="FsCodec.NewtonsoftJson" Version="2.3.2" />
<PackageReference Include="FsCodec.SystemTextJson" Version="2.3.2" />
<PackageReference Include="FsCodec.NewtonsoftJson" Version="3.0.0-rc.2" />
<PackageReference Include="FsCodec.SystemTextJson" Version="3.0.0-rc.2" />

<ProjectReference Include="..\..\..\src\Equinox\Equinox.fsproj" />
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions samples/Store/Domain/Favorites.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ module Events =
| Favorited of Favorited
| Unfavorited of Unfavorited
interface TypeShape.UnionContract.IUnionContract
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codecStj = FsCodec.SystemTextJson.Codec.Create<Event>()
let codec = EventCodec.create<Event>()
let codecJe = EventCodec.createJson<Event>()

module Fold =

Expand Down
13 changes: 11 additions & 2 deletions samples/Store/Domain/Infrastructure.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[<AutoOpen>]
module Domain.Infrastructure

open FsCodec.NewtonsoftJson
open FSharp.UMX
open Newtonsoft.Json
open System
Expand Down Expand Up @@ -40,7 +39,7 @@ type SkuId private (id : string) =
[<Obsolete>] new() = SkuId(Guid.NewGuid())
/// Represent as a Guid.ToString("N") output externally
and private SkuIdJsonConverter() =
inherit JsonIsomorphism<SkuId, string>()
inherit FsCodec.NewtonsoftJson.JsonIsomorphism<SkuId, string>()
/// Renders as per `Guid.ToString("N")`, i.e. no dashes
override _.Pickle value = string value
/// Input must be a `Guid.Parse`able value
Expand Down Expand Up @@ -75,3 +74,13 @@ module ClientId = let toString (value : ClientId) : string = Guid.toStringN %val
type InventoryItemId = Guid<inventoryItemId>
and [<Measure>] inventoryItemId
module InventoryItemId = let toString (value : InventoryItemId) : string = Guid.toStringN %value

module EventCodec =

/// For CosmosStore - we encode to JsonElement as that's what the store talks
let createJson<'t when 't :> TypeShape.UnionContract.IUnionContract> () =
FsCodec.SystemTextJson.CodecJsonElement.Create<'t>()

/// For stores other than CosmosStore, we encode to UTF-8 and have the store do the right thing
let create<'t when 't :> TypeShape.UnionContract.IUnionContract> () =
FsCodec.NewtonsoftJson.Codec.Create<'t>()
2 changes: 1 addition & 1 deletion samples/Store/Domain/SavedForLater.fs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module Events =
/// Addition of a collection of skus to the list
| Added of Added
interface TypeShape.UnionContract.IUnionContract
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codec = EventCodec.create<Event>()

module Fold =
open Events
Expand Down
9 changes: 5 additions & 4 deletions samples/Store/Integration/CartIntegration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@ open Domain
open Equinox
open Equinox.CosmosStore.Integration.CosmosFixtures
open Swensen.Unquote
open System

let fold, initial = Cart.Fold.fold, Cart.Fold.initial
let snapshot = Cart.Fold.isOrigin, Cart.Fold.snapshot

let createMemoryStore () = MemoryStore.VolatileStore<byte[]>()
let createMemoryStore () = MemoryStore.VolatileStore<ReadOnlyMemory<byte>>()
let createServiceMemory log store =
Cart.create log (MemoryStore.MemoryStoreCategory(store, Cart.Events.codec, fold, initial).Resolve)

let codec = Cart.Events.codec
let codecStj = Cart.Events.codecStj
let codecJe = Cart.Events.codecJe

let resolveGesStreamWithRollingSnapshots context =
EventStore.EventStoreCategory(context, codec, fold, initial, access = EventStore.AccessStrategy.RollingSnapshots snapshot).Resolve
let resolveGesStreamWithoutCustomAccessStrategy context =
EventStore.EventStoreCategory(context, codec, fold, initial).Resolve

let resolveCosmosStreamWithSnapshotStrategy context =
CosmosStore.CosmosStoreCategory(context, codecStj, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.Snapshot snapshot).Resolve
CosmosStore.CosmosStoreCategory(context, codecJe, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.Snapshot snapshot).Resolve
let resolveCosmosStreamWithoutCustomAccessStrategy context =
CosmosStore.CosmosStoreCategory(context, codecStj, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.Unoptimized).Resolve
CosmosStore.CosmosStoreCategory(context, codecJe, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.Unoptimized).Resolve

let addAndThenRemoveItemsManyTimesExceptTheLastOne context cartId skuId (service: Cart.Service) count =
service.ExecuteManyAsync(cartId, false, seq {
Expand Down
7 changes: 4 additions & 3 deletions samples/Store/Integration/CodecIntegration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ let codec = FsCodec.NewtonsoftJson.Codec.Create()

[<AutoData(MaxTest=100)>]
let ``Can roundtrip, rendering correctly`` (x: SimpleDu) =
let serialized = codec.Encode(None,x)
render x =! if serialized.Data = null then null else System.Text.Encoding.UTF8.GetString(serialized.Data)
let adapted = FsCodec.Core.TimelineEvent.Create(-1L, serialized.EventType, serialized.Data)
let serialized = codec.Encode(None, x)
let d = serialized.Data
render x =! if d.IsEmpty then null else System.Text.Encoding.UTF8.GetString(d.Span)
let adapted = FsCodec.Core.TimelineEvent.Create(-1L, serialized.EventType, d)
let deserialized = codec.TryDecode adapted |> Option.get
deserialized =! x
8 changes: 4 additions & 4 deletions samples/Store/Integration/ContactPreferencesIntegration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ let createServiceMemory log store =
ContactPreferences.create log (MemoryStore.MemoryStoreCategory(store, FsCodec.Box.Codec.Create(), fold, initial).Resolve)

let codec = ContactPreferences.Events.codec
let codecStj = ContactPreferences.Events.codecStj
let codecJe = ContactPreferences.Events.codecJe
let resolveStreamGesWithOptimizedStorageSemantics context =
EventStore.EventStoreCategory(context 1, codec, fold, initial, access = EventStore.AccessStrategy.LatestKnownEvent).Resolve
let resolveStreamGesWithoutAccessStrategy context =
EventStore.EventStoreCategory(context defaultBatchSize, codec, fold, initial).Resolve

let resolveStreamCosmosWithLatestKnownEventSemantics context =
CosmosStore.CosmosStoreCategory(context, codecStj, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.LatestKnownEvent).Resolve
CosmosStore.CosmosStoreCategory(context, codecJe, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.LatestKnownEvent).Resolve
let resolveStreamCosmosUnoptimized context =
CosmosStore.CosmosStoreCategory(context, codecStj, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.Unoptimized).Resolve
CosmosStore.CosmosStoreCategory(context, codecJe, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.Unoptimized).Resolve
let resolveStreamCosmosRollingUnfolds context =
let access = CosmosStore.AccessStrategy.Custom(ContactPreferences.Fold.isOrigin, ContactPreferences.Fold.transmute)
CosmosStore.CosmosStoreCategory(context, codecStj, fold, initial, CosmosStore.CachingStrategy.NoCaching, access).Resolve
CosmosStore.CosmosStoreCategory(context, codecJe, fold, initial, CosmosStore.CachingStrategy.NoCaching, access).Resolve

type Tests(testOutputHelper) =
let testOutput = TestOutput testOutputHelper
Expand Down
10 changes: 5 additions & 5 deletions samples/Store/Integration/FavoritesIntegration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,26 @@ let createServiceMemory log store =
Favorites.create log (MemoryStore.MemoryStoreCategory(store, FsCodec.Box.Codec.Create(), fold, initial).Resolve)

let codec = Favorites.Events.codec
let codecStj = Favorites.Events.codecStj
let codecJe = Favorites.Events.codecJe
let createServiceGes log context =
let cat = EventStore.EventStoreCategory(context, codec, fold, initial, access = EventStore.AccessStrategy.RollingSnapshots snapshot)
Favorites.create log cat.Resolve

let createServiceCosmosSnapshotsUncached log context =
let cat = CosmosStore.CosmosStoreCategory(context, codecStj, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.Snapshot snapshot)
let cat = CosmosStore.CosmosStoreCategory(context, codecJe, fold, initial, CosmosStore.CachingStrategy.NoCaching, CosmosStore.AccessStrategy.Snapshot snapshot)
Favorites.create log cat.Resolve

let createServiceCosmosRollingStateUncached log context =
let access = CosmosStore.AccessStrategy.RollingState Favorites.Fold.snapshot
let cat = CosmosStore.CosmosStoreCategory(context, codecStj, fold, initial, CosmosStore.CachingStrategy.NoCaching, access)
let cat = CosmosStore.CosmosStoreCategory(context, codecJe, fold, initial, CosmosStore.CachingStrategy.NoCaching, access)
Favorites.create log cat.Resolve

let createServiceCosmosUnoptimizedButCached log context =
let access = CosmosStore.AccessStrategy.Unoptimized
let caching =
let cache = Equinox.Cache ("name", 10)
let cache = Cache ("name", 10)
CosmosStore.CachingStrategy.SlidingWindow (cache, System.TimeSpan.FromMinutes 20.)
let cat = CosmosStore.CosmosStoreCategory(context, codecStj, fold, initial, caching, access)
let cat = CosmosStore.CosmosStoreCategory(context, codecJe, fold, initial, caching, access)
Favorites.create log cat.Resolve

type Command =
Expand Down
3 changes: 0 additions & 3 deletions samples/Store/Integration/Integration.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<WarningLevel>5</WarningLevel>
<DisableImplicitSystemValueTupleReference>true</DisableImplicitSystemValueTupleReference>
</PropertyGroup>

Expand All @@ -29,7 +27,6 @@

<ItemGroup>
<PackageReference Include="FsCheck.xUnit" Version="2.16.4" />
<PackageReference Include="FsCodec.Box" Version="2.3.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="5.1.1" />
<PackageReference Include="unquote" Version="6.1.0" />
Expand Down
2 changes: 1 addition & 1 deletion samples/TodoBackend/Todo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ module Events =
| Cleared
| Snapshotted of Snapshotted
interface TypeShape.UnionContract.IUnionContract
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codec = EventCodec.create<Event> ()

module Fold =
type State = { items : Events.Todo list; nextId : int }
Expand Down
4 changes: 1 addition & 3 deletions samples/TodoBackend/TodoBackend.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<WarningLevel>5</WarningLevel>
<IsTestProject>false</IsTestProject>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
<DisableImplicitSystemValueTupleReference>true</DisableImplicitSystemValueTupleReference>
</PropertyGroup>
Expand All @@ -13,7 +11,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="FSharp.Core" Version="4.3.4" />
<PackageReference Include="FSharp.Core" Version="4.5.4" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit a5bb269

Please sign in to comment.