Skip to content

Commit

Permalink
Target FsCodec a14
Browse files Browse the repository at this point in the history
  • Loading branch information
bartelink committed Jan 4, 2025
1 parent 3ac10f1 commit 2b7dc75
Show file tree
Hide file tree
Showing 11 changed files with 28 additions and 29 deletions.
4 changes: 2 additions & 2 deletions samples/Infrastructure/Services.fs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ type Store(store) =
MemoryStore.MemoryStoreCategory(store, name, codec, fold, initial)
| Store.Config.Cosmos (store, caching, unfolds) ->
let accessStrategy = if unfolds then CosmosStore.AccessStrategy.Snapshot snapshot else CosmosStore.AccessStrategy.Unoptimized
CosmosStore.CosmosStoreCategory<'event,'state,_>(store, name, FsCodec.SystemTextJson.Encoding.EncodeTryCompressUtf8 codec, fold, initial, accessStrategy, caching)
CosmosStore.CosmosStoreCategory<'event,'state,_>(store, name, FsCodec.SystemTextJson.Encoder.CompressedUtf8 codec, fold, initial, accessStrategy, caching)
| Store.Config.Dynamo (store, caching, unfolds) ->
let accessStrategy = if unfolds then DynamoStore.AccessStrategy.Snapshot snapshot else DynamoStore.AccessStrategy.Unoptimized
DynamoStore.DynamoStoreCategory<'event,'state,_>(store, name, FsCodec.Compression.EncodeTryCompress codec, fold, initial, accessStrategy, caching)
DynamoStore.DynamoStoreCategory<'event,'state,_>(store, name, FsCodec.Encoder.Compressed codec, fold, initial, accessStrategy, caching)
| Store.Config.Es (context, caching, unfolds) ->
let accessStrategy = if unfolds then EventStoreDb.AccessStrategy.RollingSnapshots snapshot else EventStoreDb.AccessStrategy.Unoptimized
EventStoreDb.EventStoreCategory<'event,'state,_>(context, name, codec, fold, initial, accessStrategy, caching)
Expand Down
2 changes: 1 addition & 1 deletion samples/Store/Domain/Domain.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<PackageReference Include="FSharp.Core" Version="6.0.7" ExcludeAssets="contentfiles" />

<PackageReference Include="FsCodec.NewtonsoftJson" Version="3.0.0" />
<PackageReference Include="FsCodec.SystemTextJson" Version="3.0.4-alpha.0.11" />
<PackageReference Include="FsCodec.SystemTextJson" Version="3.0.4-alpha.0.14" />

<ProjectReference Include="..\..\..\src\Equinox\Equinox.fsproj" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion samples/Store/Domain/Infrastructure.fs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ module EventCodec =

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

/// For stores other than CosmosStore, we encode to UTF-8 and have the store do the right thing
let gen<'t when 't :> TypeShape.UnionContract.IUnionContract> =
Expand Down
2 changes: 1 addition & 1 deletion samples/Tutorial/Infrastructure.fs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module EventCodec =

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

/// For stores other than CosmosStore, we encode to UTF-8 and have the store do the right thing
let gen<'t when 't :> TypeShape.UnionContract.IUnionContract> =
Expand Down
2 changes: 1 addition & 1 deletion samples/Tutorial/Tutorial.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

<ItemGroup>
<PackageReference Include="MinVer" Version="5.0.0" PrivateAssets="All" />
<PackageReference Include="FsCodec.SystemTextJson" Version="3.0.4-alpha.0.11" />
<PackageReference Include="FsCodec.SystemTextJson" Version="3.0.4-alpha.0.14" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="7.0.0" />
</ItemGroup>
Expand Down
15 changes: 8 additions & 7 deletions src/Equinox.CosmosStore/CosmosStore.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ type EncodedBody = (struct (int * JsonElement))
/// Interpretation of EncodedBody data is an external concern from the perspective of the Store
/// The idiomatic implementation of the encoding logic is FsCodec.SystemTextJson.Compression, in versions 3.1.0 or later
/// That implementation provides complete interop with encodings produced by Equinox.Cosmos/CosmosStore from V1 onwards, including integrated Deflate compression
module internal EncodedBody =
module EncodedBody =
let internal jsonRawText: EncodedBody -> string = ValueTuple.snd >> _.GetRawText()
let internal jsonUtf8Bytes = jsonRawText >> System.Text.Encoding.UTF8.GetByteCount
let [<Literal>] deflateEncoding = 1
// prior to the addition of the `D` field in 4.1.0, the integrated compression support
// was predicated entirely on a JSON String `d` value in the Unfold as implying it was UTF8->Deflate->Base64 encoded
let parseUnfold = function struct (0, e: JsonElement) when e.ValueKind = JsonValueKind.String -> struct (deflateEncoding, e) | x -> x
let [<Literal>] private deflateEncoding = 1
/// prior to the addition of the `D` field in 4.1.0, the integrated compression support
/// was predicated entirely on a JSON String `d` value in the Unfold as implying it was UTF8 -> Deflate -> Base64 encoded
let ofUnfoldBody struct (enc, data: JsonElement): EncodedBody =
if enc = 0 && data.ValueKind = JsonValueKind.String then (deflateEncoding, data) else (enc, data)

/// A single Domain Event from the array held in a Batch
[<NoEquality; NoComparison>]
Expand Down Expand Up @@ -108,7 +109,7 @@ type Unfold =
[<Serialization.JsonIgnore(Condition = Serialization.JsonIgnoreCondition.WhenWritingDefault)>]
M: int }
member x.ToTimelineEvent(): ITimelineEvent<EncodedBody> =
FsCodec.Core.TimelineEvent.Create(x.i, x.c, EncodedBody.parseUnfold (x.D, x.d), (x.M, x.m), Guid.Empty, null, null, x.t, isUnfold = true)
FsCodec.Core.TimelineEvent.Create(x.i, x.c, EncodedBody.ofUnfoldBody (x.D, x.d), (x.M, x.m), Guid.Empty, null, null, x.t, isUnfold = true)
// Arrays are not indexed by default. 1. enable filtering by `c`ase 2. index uncompressed fields within unfolds for filtering
static member internal IndexedPaths = [| "/u/[]/c/?"; "/u/[]/d/*" |]

Expand Down Expand Up @@ -255,7 +256,7 @@ module Log =
f log
retryPolicy.Execute withLoggingContextWrapping

let internal eventLen (x: #IEventData<_>) = EncodedBody.jsonUtf8Bytes x.Data + EncodedBody.jsonUtf8Bytes x.Meta + 80
let internal eventLen (x: #IEventData<EncodedBody>) = EncodedBody.jsonUtf8Bytes x.Data + EncodedBody.jsonUtf8Bytes x.Meta + 80
let internal batchLen = Seq.sumBy eventLen
[<RequireQualifiedAccess>]
type Operation = Tip | Tip404 | Tip304 | Query | Index | Write | Resync | Conflict | Prune | Delete | Trim
Expand Down
4 changes: 2 additions & 2 deletions tests/Equinox.CosmosStore.Integration/AccessStrategies.fs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ module SequenceCheck =
| Add of {| value : int |}
interface TypeShape.UnionContract.IUnionContract
#if STORE_DYNAMO
let codec = FsCodec.SystemTextJson.Codec.Create<Event>() |> FsCodec.Compression.EncodeTryCompress
let codec = FsCodec.SystemTextJson.Codec.Create<Event>() |> FsCodec.Encoder.Compressed
#else
let codec = FsCodec.SystemTextJson.CodecJsonElement.Create<Event>() |> FsCodec.SystemTextJson.Encoding.EncodeTryCompress
let codec = FsCodec.SystemTextJson.CodecJsonElement.Create<Event>() |> FsCodec.SystemTextJson.Encoder.Compressed
#endif

module Fold =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ open System

type TestEvents() =
static member private Create(i, ?eventType, ?json) =
let enc = System.Text.Json.JsonSerializer.SerializeToElement >> FsCodec.SystemTextJson.Encoding.FromJsonElement
let enc = System.Text.Json.JsonSerializer.SerializeToElement >> FsCodec.SystemTextJson.Encoding.OfJsonElement
FsCodec.Core.EventData.Create
( sprintf "%s:%d" (defaultArg eventType "test_event") i,
enc (defaultArg json "{\"d\":\"d\"}"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ open Equinox.CosmosStore.Integration.CosmosFixtures
module Cart =
let fold, initial = Cart.Fold.fold, Cart.Fold.initial
#if STORE_DYNAMO
let codec = Cart.Events.codec |> FsCodec.Compression.EncodeTryCompress
let codec = Cart.Events.codec |> FsCodec.Encoder.Compressed
#else
let codec = Cart.Events.codecJe
#endif
Expand Down Expand Up @@ -49,7 +49,7 @@ module ContactPreferences =
let fold, initial = ContactPreferences.Fold.fold, ContactPreferences.Fold.initial
module ClientId = let gen (): ContactPreferences.ClientId = Guid.gen () |> Guid.toStringN |> ContactPreferences.ClientId
#if STORE_DYNAMO
let codec = ContactPreferences.Events.codec |> FsCodec.Compression.EncodeTryCompress
let codec = ContactPreferences.Events.codec |> FsCodec.Encoder.Compressed
#else
let codec = ContactPreferences.Events.codecJe
#endif
Expand Down
10 changes: 5 additions & 5 deletions tests/Equinox.CosmosStore.Integration/FsCodecCompressionTests.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Prior to version v 4.1.0, CosmosStore owned:
// - compression of snapshots (and APIs controlling conditionally of that)
// - inflation of snapshots
// This is now an external concern, fully implemented by APIs presented in FsCodec.SystemTextJson.Compression v 3.1.0 and later
// This is now an external concern, fully implemented by APIs presented in FsCodec.SystemTextJson.Encod* v 3.1.0 and later
// These tests are a sanity check pinning the basic mechanisms that are now externalized; any more thorough tests should be maintained in FsCodec
// NOTE there is no strong dependency on FsCodec; CosmosStore is happy to roundtrip arbitrary pairs of D/d and M/m values
// NOTE prior to v 4.1.0, CosmosStore provided a System.Text.Json integration for Microsoft.Azure.Cosmos
Expand Down Expand Up @@ -38,14 +38,14 @@ type CoreBehaviors() =

[<Fact>]
let ``serializes, achieving expected compression`` () =
let encoded = eventCodec |> FsCodec.SystemTextJson.Encoding.EncodeTryCompress |> _.Encode((), A { embed = String('x',5000) })
let encoded = eventCodec |> FsCodec.SystemTextJson.Encoder.Compressed |> _.Encode((), A { embed = String('x',5000) })
let res = ser encoded
test <@ res.Contains "\"d\":\"" && res.Length < 138 && res.Contains "\"D\":2" @>

let codec compress =
let forceCompression: FsCodec.SystemTextJson.CompressionOptions = { minSize = 0; minGain = -1000 }
if compress then FsCodec.SystemTextJson.Encoding.EncodeTryCompress(eventCodec, options = forceCompression)
else FsCodec.SystemTextJson.Encoding.EncodeUncompressed eventCodec
let forceCompression: FsCodec.CompressionOptions = { minSize = 0; minGain = -1000 }
if compress then FsCodec.SystemTextJson.Encoder.Compressed(eventCodec, options = forceCompression)
else FsCodec.SystemTextJson.Encoder.Uncompressed eventCodec

[<Property>]
let roundtrips compress value =
Expand Down
10 changes: 4 additions & 6 deletions tools/Equinox.Tool/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -483,8 +483,6 @@ module CosmosQuery =
open Equinox.CosmosStore.Linq.Internal
open FSharp.Control
let inline miB x = Equinox.CosmosStore.Linq.Internal.miB x
type System.Text.Json.JsonElement with
member x.Utf8ByteCount = if x.ValueKind = System.Text.Json.JsonValueKind.Null then 0 else x.GetRawText() |> System.Text.Encoding.UTF8.GetByteCount
type System.Text.Json.JsonDocument with
member x.Cast<'T>() = System.Text.Json.JsonSerializer.Deserialize<'T>(x.RootElement)
member x.Timestamp =
Expand All @@ -498,9 +496,9 @@ module CosmosQuery =
| _ -> ()
let selectedFields =
match a.Mode with
| Mode.Default -> "c._etag, c.p, c.u[0].d"
| Mode.SnapOnly -> "c.u[0].d"
| Mode.SnapWithStream -> "c.p, c.u[0].d"
| Mode.Default -> "c._etag, c.p, c.u[0].D, c.u[0].d"
| Mode.SnapOnly -> "c.u[0].D, c.u[0].d"
| Mode.SnapWithStream -> "c.p, c.u[0].D, c.u[0].d"
| Mode.ReadOnly -> "c.u" // TOCONSIDER remove; adjust TryLoad/TryHydrateTip
| Mode.ReadWithStream -> "c.p, c.u" // TOCONSIDER remove; adjust TryLoad/TryHydrateTip
| Mode.Raw -> "*"
Expand Down Expand Up @@ -576,7 +574,7 @@ module CosmosTop =
scratch.Position
let inflatedUtf8Size x =
scratch.Position <- 0L
FsCodec.SystemTextJson.Encoding.ExpandTo(scratch, x)
FsCodec.SystemTextJson.Encoding.ToStream(scratch, x)
scratch.Position
let infSize dataField formatField (x: JsonElement) =
match x.TryProp dataField, x.TryProp formatField with
Expand Down

0 comments on commit 2b7dc75

Please sign in to comment.