From d8dd9295618c292f1c3bba0acc087b9529c365f0 Mon Sep 17 00:00:00 2001 From: thefringeninja <495495+thefringeninja@users.noreply.github.com> Date: Wed, 16 Sep 2020 16:46:13 +0200 Subject: [PATCH 1/4] use stream revision echoed from the server --- .../EventStoreClient.Append.cs | 37 +++++++++++-------- .../WrongExpectedVersionResult.cs | 15 ++++++++ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/EventStore.Client.Streams/EventStoreClient.Append.cs b/src/EventStore.Client.Streams/EventStoreClient.Append.cs index 026126718..543ac4632 100644 --- a/src/EventStore.Client.Streams/EventStoreClient.Append.cs +++ b/src/EventStore.Client.Streams/EventStoreClient.Append.cs @@ -138,40 +138,47 @@ await call.RequestStream.WriteAsync(new AppendReq { header.Options.StreamIdentifier, writeResult.LogPosition, writeResult.NextExpectedStreamRevision); } else { if (response.WrongExpectedVersion != null) { - var currentRevision = response.WrongExpectedVersion.CurrentRevisionOptionCase switch { - AppendResp.Types.WrongExpectedVersion.CurrentRevisionOptionOneofCase.NoStream => + var actualStreamRevision = response.WrongExpectedVersion.CurrentRevisionOptionCase switch { + AppendResp.Types.WrongExpectedVersion.CurrentRevisionOptionOneofCase.None => StreamRevision.None, _ => new StreamRevision(response.WrongExpectedVersion.CurrentRevision) }; _log.LogDebug( "Append to stream failed with Wrong Expected Version - {streamName}/{expectedRevision}/{currentRevision}", - header.Options.StreamIdentifier, new StreamRevision(header.Options.Revision), currentRevision); - + header.Options.StreamIdentifier, new StreamRevision(header.Options.Revision), actualStreamRevision); + if (operationOptions.ThrowOnAppendFailure) { - if (header.Options.ExpectedStreamRevisionCase == - AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.Revision) { + if (response.WrongExpectedVersion.ExpectedRevisionOptionCase == AppendResp.Types + .WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedRevision) { throw new WrongExpectedVersionException(header.Options.StreamIdentifier, - new StreamRevision(header.Options.Revision), - currentRevision); + new StreamRevision(response.WrongExpectedVersion.ExpectedRevision), + actualStreamRevision); } - var streamState = header.Options.ExpectedStreamRevisionCase switch { - AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.Any => + var streamState = response.WrongExpectedVersion.ExpectedRevisionOptionCase switch { + AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.Any => StreamState.Any, - AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.NoStream => + AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.None => StreamState.NoStream, - AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.StreamExists => + AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.StreamExists => StreamState.StreamExists, _ => throw new InvalidOperationException() }; throw new WrongExpectedVersionException(header.Options.StreamIdentifier, - streamState, currentRevision); + streamState, actualStreamRevision); + } + + if (response.WrongExpectedVersion.CurrentRevisionOptionCase == AppendResp.Types + .WrongExpectedVersion.CurrentRevisionOptionOneofCase.CurrentRevision) { + writeResult = new WrongExpectedVersionResult(header.Options.StreamIdentifier, + new StreamRevision(response.WrongExpectedVersion.ExpectedRevision)); + } else { + writeResult = new WrongExpectedVersionResult(header.Options.StreamIdentifier, + StreamRevision.None); } - writeResult = new WrongExpectedVersionResult( - header.Options.StreamIdentifier, currentRevision); } else { throw new InvalidOperationException("The operation completed with an unexpected result."); } diff --git a/src/EventStore.Client.Streams/WrongExpectedVersionResult.cs b/src/EventStore.Client.Streams/WrongExpectedVersionResult.cs index a8934b48a..cca32ba9b 100644 --- a/src/EventStore.Client.Streams/WrongExpectedVersionResult.cs +++ b/src/EventStore.Client.Streams/WrongExpectedVersionResult.cs @@ -34,5 +34,20 @@ public WrongExpectedVersionResult(string streamName, StreamRevision nextExpected NextExpectedStreamRevision = nextExpectedStreamRevision; LogPosition = default; } + + /// + /// Construct a new . + /// + /// + /// + /// + public WrongExpectedVersionResult(string streamName, StreamRevision nextExpectedStreamRevision, + StreamRevision actualStreamRevision) { + StreamName = streamName; + ActualVersion = actualStreamRevision.ToInt64(); + NextExpectedVersion = nextExpectedStreamRevision.ToInt64(); + NextExpectedStreamRevision = nextExpectedStreamRevision; + LogPosition = default; + } } } From 7c206b2d5a7836473b6d4e108678596c7d5bf018 Mon Sep 17 00:00:00 2001 From: thefringeninja <495495+thefringeninja@users.noreply.github.com> Date: Sat, 19 Sep 2020 10:25:21 +0200 Subject: [PATCH 2/4] added missing field in proto --- src/EventStore.Client.Common/protos/streams.proto | 7 ++++--- .../EventStoreClient.Append.cs | 12 ++++++------ .../EventStoreClientFixtureBase.cs | 2 -- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/EventStore.Client.Common/protos/streams.proto b/src/EventStore.Client.Common/protos/streams.proto index 8594af31b..32cfb9f18 100644 --- a/src/EventStore.Client.Common/protos/streams.proto +++ b/src/EventStore.Client.Common/protos/streams.proto @@ -168,12 +168,13 @@ message AppendResp { message WrongExpectedVersion { oneof current_revision_option { uint64 current_revision = 1; - event_store.client.Empty no_stream = 2; + event_store.client.Empty current_no_stream = 2; } oneof expected_revision_option { uint64 expected_revision = 3; - event_store.client.Empty any = 4; - event_store.client.Empty stream_exists = 5; + event_store.client.Empty expected_any = 4; + event_store.client.Empty expected_stream_exists = 5; + event_store.client.Empty expected_no_stream = 6; } } } diff --git a/src/EventStore.Client.Streams/EventStoreClient.Append.cs b/src/EventStore.Client.Streams/EventStoreClient.Append.cs index 543ac4632..8c15f3cae 100644 --- a/src/EventStore.Client.Streams/EventStoreClient.Append.cs +++ b/src/EventStore.Client.Streams/EventStoreClient.Append.cs @@ -139,7 +139,7 @@ await call.RequestStream.WriteAsync(new AppendReq { } else { if (response.WrongExpectedVersion != null) { var actualStreamRevision = response.WrongExpectedVersion.CurrentRevisionOptionCase switch { - AppendResp.Types.WrongExpectedVersion.CurrentRevisionOptionOneofCase.None => + AppendResp.Types.WrongExpectedVersion.CurrentRevisionOptionOneofCase.CurrentNoStream => StreamRevision.None, _ => new StreamRevision(response.WrongExpectedVersion.CurrentRevision) }; @@ -156,18 +156,18 @@ await call.RequestStream.WriteAsync(new AppendReq { actualStreamRevision); } - var streamState = response.WrongExpectedVersion.ExpectedRevisionOptionCase switch { - AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.Any => + var expectedStreamState = response.WrongExpectedVersion.ExpectedRevisionOptionCase switch { + AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedAny => StreamState.Any, - AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.None => + AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedNoStream => StreamState.NoStream, - AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.StreamExists => + AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedStreamExists => StreamState.StreamExists, _ => throw new InvalidOperationException() }; throw new WrongExpectedVersionException(header.Options.StreamIdentifier, - streamState, actualStreamRevision); + expectedStreamState, actualStreamRevision); } if (response.WrongExpectedVersion.CurrentRevisionOptionCase == AppendResp.Types diff --git a/test/EventStore.Client.Tests.Common/EventStoreClientFixtureBase.cs b/test/EventStore.Client.Tests.Common/EventStoreClientFixtureBase.cs index 3155cafd0..7e5a859f2 100644 --- a/test/EventStore.Client.Tests.Common/EventStoreClientFixtureBase.cs +++ b/test/EventStore.Client.Tests.Common/EventStoreClientFixtureBase.cs @@ -12,10 +12,8 @@ using System.Threading; using System.Threading.Tasks; using Ductus.FluentDocker.Builders; -using Ductus.FluentDocker.Commands; using Ductus.FluentDocker.Model.Builders; using Ductus.FluentDocker.Services; -using Ductus.FluentDocker.Services.Extensions; using Polly; using Serilog; using Serilog.Events; From 8e6e098cf868556b812a4f185e45086c376188b5 Mon Sep 17 00:00:00 2001 From: thefringeninja <495495+thefringeninja@users.noreply.github.com> Date: Tue, 22 Sep 2020 15:02:46 +0200 Subject: [PATCH 3/4] update proto --- .../protos/streams.proto | 22 +++++++++---- .../EventStoreClient.Append.cs | 33 ++++++++++--------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/EventStore.Client.Common/protos/streams.proto b/src/EventStore.Client.Common/protos/streams.proto index 32cfb9f18..8c3bbbb7c 100644 --- a/src/EventStore.Client.Common/protos/streams.proto +++ b/src/EventStore.Client.Common/protos/streams.proto @@ -166,16 +166,26 @@ message AppendResp { } message WrongExpectedVersion { + oneof current_revision_option_20_6_0 { + uint64 current_revision_20_6_0 = 1; + event_store.client.Empty no_stream_20_6_0 = 2; + } + oneof expected_revision_option_20_6_0 { + uint64 expected_revision_20_6_0 = 3; + event_store.client.Empty any_20_6_0 = 4; + event_store.client.Empty stream_exists_20_6_0 = 5; + } oneof current_revision_option { - uint64 current_revision = 1; - event_store.client.Empty current_no_stream = 2; + uint64 current_revision = 6; + event_store.client.Empty current_no_stream = 7; } oneof expected_revision_option { - uint64 expected_revision = 3; - event_store.client.Empty expected_any = 4; - event_store.client.Empty expected_stream_exists = 5; - event_store.client.Empty expected_no_stream = 6; + uint64 expected_revision = 8; + event_store.client.Empty expected_any = 9; + event_store.client.Empty expected_stream_exists = 10; + event_store.client.Empty expected_no_stream = 11; } + } } diff --git a/src/EventStore.Client.Streams/EventStoreClient.Append.cs b/src/EventStore.Client.Streams/EventStoreClient.Append.cs index 8c15f3cae..8f6473213 100644 --- a/src/EventStore.Client.Streams/EventStoreClient.Append.cs +++ b/src/EventStore.Client.Streams/EventStoreClient.Append.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using EventStore.Client.Streams; using Google.Protobuf; -using Grpc.Core; using Microsoft.Extensions.Logging; #nullable enable @@ -125,9 +124,8 @@ await call.RequestStream.WriteAsync(new AppendReq { var response = await call.ResponseAsync.ConfigureAwait(false); if (response.Success != null) { - writeResult = new SuccessResult( - response.Success.CurrentRevisionOptionCase == - AppendResp.Types.Success.CurrentRevisionOptionOneofCase.NoStream + writeResult = new SuccessResult(response.Success.CurrentRevisionOptionCase == + AppendResp.Types.Success.CurrentRevisionOptionOneofCase.NoStream ? StreamRevision.None : new StreamRevision(response.Success.CurrentRevision), response.Success.PositionOptionCase == AppendResp.Types.Success.PositionOptionOneofCase.Position @@ -139,14 +137,15 @@ await call.RequestStream.WriteAsync(new AppendReq { } else { if (response.WrongExpectedVersion != null) { var actualStreamRevision = response.WrongExpectedVersion.CurrentRevisionOptionCase switch { - AppendResp.Types.WrongExpectedVersion.CurrentRevisionOptionOneofCase.CurrentNoStream => - StreamRevision.None, - _ => new StreamRevision(response.WrongExpectedVersion.CurrentRevision) - }; + AppendResp.Types.WrongExpectedVersion.CurrentRevisionOptionOneofCase.CurrentNoStream => + StreamRevision.None, + _ => new StreamRevision(response.WrongExpectedVersion.CurrentRevision) + }; _log.LogDebug( "Append to stream failed with Wrong Expected Version - {streamName}/{expectedRevision}/{currentRevision}", - header.Options.StreamIdentifier, new StreamRevision(header.Options.Revision), actualStreamRevision); + header.Options.StreamIdentifier, new StreamRevision(header.Options.Revision), + actualStreamRevision); if (operationOptions.ThrowOnAppendFailure) { if (response.WrongExpectedVersion.ExpectedRevisionOptionCase == AppendResp.Types @@ -158,11 +157,11 @@ await call.RequestStream.WriteAsync(new AppendReq { var expectedStreamState = response.WrongExpectedVersion.ExpectedRevisionOptionCase switch { AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedAny => - StreamState.Any, + StreamState.Any, AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedNoStream => - StreamState.NoStream, + StreamState.NoStream, AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedStreamExists => - StreamState.StreamExists, + StreamState.StreamExists, _ => throw new InvalidOperationException() }; @@ -170,13 +169,15 @@ await call.RequestStream.WriteAsync(new AppendReq { expectedStreamState, actualStreamRevision); } - if (response.WrongExpectedVersion.CurrentRevisionOptionCase == AppendResp.Types - .WrongExpectedVersion.CurrentRevisionOptionOneofCase.CurrentRevision) { + if (response.WrongExpectedVersion.ExpectedRevisionOptionCase == AppendResp.Types + .WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedRevision) { writeResult = new WrongExpectedVersionResult(header.Options.StreamIdentifier, - new StreamRevision(response.WrongExpectedVersion.ExpectedRevision)); + new StreamRevision(response.WrongExpectedVersion.ExpectedRevision), + actualStreamRevision); } else { writeResult = new WrongExpectedVersionResult(header.Options.StreamIdentifier, - StreamRevision.None); + StreamRevision.None, + actualStreamRevision); } } else { From e00ae1fd224d64bcd912bcb5acb72f78f9e0478a Mon Sep 17 00:00:00 2001 From: thefringeninja <495495+thefringeninja@users.noreply.github.com> Date: Wed, 23 Sep 2020 15:08:00 +0200 Subject: [PATCH 4/4] fixed broken tests --- src/EventStore.Client.Streams/ConditionalWriteResult.cs | 2 +- .../Exceptions/WrongExpectedVersionException.cs | 7 +++++++ test/EventStore.Client.Streams.Tests/append_to_stream.cs | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/EventStore.Client.Streams/ConditionalWriteResult.cs b/src/EventStore.Client.Streams/ConditionalWriteResult.cs index 608764513..945edce71 100644 --- a/src/EventStore.Client.Streams/ConditionalWriteResult.cs +++ b/src/EventStore.Client.Streams/ConditionalWriteResult.cs @@ -49,7 +49,7 @@ internal static ConditionalWriteResult FromWriteResult(IWriteResult writeResult) }; internal static ConditionalWriteResult FromWrongExpectedVersion(WrongExpectedVersionException ex) - => new ConditionalWriteResult(ex.ActualStreamRevision, Position.End, + => new ConditionalWriteResult(ex.ExpectedStreamRevision, Position.End, ConditionalWriteStatus.VersionMismatch); /// diff --git a/src/EventStore.Client/Exceptions/WrongExpectedVersionException.cs b/src/EventStore.Client/Exceptions/WrongExpectedVersionException.cs index 466756d0d..dc7c02918 100644 --- a/src/EventStore.Client/Exceptions/WrongExpectedVersionException.cs +++ b/src/EventStore.Client/Exceptions/WrongExpectedVersionException.cs @@ -28,6 +28,11 @@ public class WrongExpectedVersionException : Exception { /// public StreamRevision ActualStreamRevision { get; } + /// + /// If available, the expected version specified for the operation that failed. + /// + public StreamRevision ExpectedStreamRevision { get; } + /// /// Constructs a new instance of with the expected and actual versions if available. /// @@ -38,6 +43,7 @@ public WrongExpectedVersionException(string streamName, StreamRevision expectedS exception) { StreamName = streamName; ActualStreamRevision = actualStreamRevision; + ExpectedStreamRevision = expectedStreamRevision; ExpectedVersion = expectedStreamRevision == StreamRevision.None ? new long?() : expectedStreamRevision.ToInt64(); ActualVersion = actualStreamRevision == StreamRevision.None ? new long?() : actualStreamRevision.ToInt64(); } @@ -56,6 +62,7 @@ public WrongExpectedVersionException(string streamName, StreamState expectedStre StreamName = streamName; ActualStreamRevision = actualStreamRevision; ActualVersion = actualStreamRevision == StreamRevision.None ? new long?() : actualStreamRevision.ToInt64(); + ExpectedStreamRevision = StreamRevision.None; } } } diff --git a/test/EventStore.Client.Streams.Tests/append_to_stream.cs b/test/EventStore.Client.Streams.Tests/append_to_stream.cs index 67827f265..60f62b7fb 100644 --- a/test/EventStore.Client.Streams.Tests/append_to_stream.cs +++ b/test/EventStore.Client.Streams.Tests/append_to_stream.cs @@ -231,7 +231,7 @@ public async Task appending_with_wrong_expected_version_to_existing_stream_retur var wrongExpectedVersionResult = (WrongExpectedVersionResult)writeResult; - Assert.Equal(StreamRevision.None, wrongExpectedVersionResult.NextExpectedStreamRevision); + Assert.Equal(new StreamRevision(1), wrongExpectedVersionResult.NextExpectedStreamRevision); } [Fact]