diff --git a/src/EventStore.Client.Common/protos/streams.proto b/src/EventStore.Client.Common/protos/streams.proto
index 8594af31b..8c3bbbb7c 100644
--- a/src/EventStore.Client.Common/protos/streams.proto
+++ b/src/EventStore.Client.Common/protos/streams.proto
@@ -166,15 +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 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 any = 4;
- event_store.client.Empty stream_exists = 5;
+ 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/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.Streams/EventStoreClient.Append.cs b/src/EventStore.Client.Streams/EventStoreClient.Append.cs
index 026126718..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
@@ -138,40 +136,50 @@ 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 =>
- StreamRevision.None,
- _ => new StreamRevision(response.WrongExpectedVersion.CurrentRevision)
- };
+ var actualStreamRevision = response.WrongExpectedVersion.CurrentRevisionOptionCase switch {
+ 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), 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 =>
- StreamState.Any,
- AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.NoStream =>
- StreamState.NoStream,
- AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.StreamExists =>
- StreamState.StreamExists,
+ var expectedStreamState = response.WrongExpectedVersion.ExpectedRevisionOptionCase switch {
+ AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedAny =>
+ StreamState.Any,
+ AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedNoStream =>
+ StreamState.NoStream,
+ AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedStreamExists =>
+ StreamState.StreamExists,
_ => throw new InvalidOperationException()
};
throw new WrongExpectedVersionException(header.Options.StreamIdentifier,
- streamState, currentRevision);
+ expectedStreamState, actualStreamRevision);
+ }
+
+ if (response.WrongExpectedVersion.ExpectedRevisionOptionCase == AppendResp.Types
+ .WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedRevision) {
+ writeResult = new WrongExpectedVersionResult(header.Options.StreamIdentifier,
+ new StreamRevision(response.WrongExpectedVersion.ExpectedRevision),
+ actualStreamRevision);
+ } else {
+ writeResult = new WrongExpectedVersionResult(header.Options.StreamIdentifier,
+ StreamRevision.None,
+ actualStreamRevision);
}
- 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;
+ }
}
}
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]
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;