Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate EventBody to FsCodec 3 conventions #323

Merged
merged 1 commit into from
May 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Migrate EventBody to FsCodec 3 conventions
  • Loading branch information
bartelink committed May 12, 2022
commit c72f407ce4fa183017569ff961a91229b1c3021d
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