Browse Source

Control version by snapshot again.

pull/680/head
Sebastian Stehle 5 years ago
parent
commit
5f30a825d9
  1. 2
      backend/src/Squidex.Domain.Apps.Entities/DomainObjectState.cs
  2. 26
      backend/src/Squidex.Infrastructure/Commands/DomainObject.cs
  3. 2
      backend/src/Squidex.Infrastructure/Commands/IDomainState.cs
  4. 5
      backend/src/Squidex.Infrastructure/Commands/SnapshotList.cs
  5. 38
      backend/tests/Squidex.Infrastructure.Tests/Commands/DomainObjectTests.cs
  6. 2
      backend/tests/Squidex.Infrastructure.Tests/TestHelpers/MyDomainState.cs

2
backend/src/Squidex.Domain.Apps.Entities/DomainObjectState.cs

@ -73,8 +73,6 @@ namespace Squidex.Domain.Apps.Entities
clone.LastModified = timestamp; clone.LastModified = timestamp;
clone.LastModifiedBy = payload.Actor; clone.LastModifiedBy = payload.Actor;
clone.Version++;
return (clone as T)!; return (clone as T)!;
} }
} }

26
backend/src/Squidex.Infrastructure/Commands/DomainObject.cs

@ -61,19 +61,23 @@ namespace Squidex.Infrastructure.Commands
if (result == null && valid) if (result == null && valid)
{ {
var snapshotCurrent = new T(); var snapshot = new T
var snapshotVersion = EtagVersion.Empty; {
Version = EtagVersion.Empty
};
snapshots.Add(snapshotCurrent, snapshotVersion, false); snapshots.Add(snapshot, snapshot.Version, false);
var allEvents = factory.WithEventSourcing(GetType(), UniqueId, @event => var allEvents = factory.WithEventSourcing(GetType(), UniqueId, @event =>
{ {
snapshotVersion++; var newVersion = snapshot.Version + 1;
if (!snapshots.Contains(snapshotVersion)) if (!snapshots.Contains(newVersion))
{ {
snapshotCurrent = Apply(snapshotCurrent, @event); snapshot = Apply(snapshot, @event);
snapshots.Add(snapshotCurrent, snapshotVersion, false); snapshot.Version = newVersion;
snapshots.Add(snapshot, newVersion, false);
return true; return true;
} }
@ -86,7 +90,7 @@ namespace Squidex.Infrastructure.Commands
(result, valid) = snapshots.Get(version); (result, valid) = snapshots.Get(version);
} }
return result ?? new T(); return result ?? new T { Version = EtagVersion.Empty };
} }
public virtual void Setup(DomainId uniqueId) public virtual void Setup(DomainId uniqueId)
@ -96,6 +100,7 @@ namespace Squidex.Infrastructure.Commands
persistence = factory.WithSnapshotsAndEventSourcing(GetType(), UniqueId, persistence = factory.WithSnapshotsAndEventSourcing(GetType(), UniqueId,
new HandleSnapshot<T>((snapshot, version) => new HandleSnapshot<T>((snapshot, version) =>
{ {
snapshot.Version = version;
snapshots.Add(snapshot, version, true); snapshots.Add(snapshot, version, true);
}), }),
@event => ApplyEvent(@event, true)); @event => ApplyEvent(@event, true));
@ -287,11 +292,14 @@ namespace Squidex.Infrastructure.Commands
private bool ApplyEvent(Envelope<IEvent> @event, bool isLoading) private bool ApplyEvent(Envelope<IEvent> @event, bool isLoading)
{ {
var newVersion = Version + 1;
var snapshotNew = Apply(Snapshot, @event); var snapshotNew = Apply(Snapshot, @event);
if (!ReferenceEquals(Snapshot, snapshotNew) || isLoading) if (!ReferenceEquals(Snapshot, snapshotNew) || isLoading)
{ {
snapshots.Add(snapshotNew, Version + 1, true); snapshotNew.Version = newVersion;
snapshots.Add(snapshotNew, newVersion, true);
return true; return true;
} }

2
backend/src/Squidex.Infrastructure/Commands/IDomainState.cs

@ -11,6 +11,8 @@ namespace Squidex.Infrastructure.Commands
{ {
public interface IDomainState<out T> public interface IDomainState<out T>
{ {
long Version { get; set; }
T Apply(Envelope<IEvent> @event); T Apply(Envelope<IEvent> @event);
} }
} }

5
backend/src/Squidex.Infrastructure/Commands/SnapshotList.cs

@ -50,7 +50,10 @@ namespace Squidex.Infrastructure.Commands
public void Clear() public void Clear()
{ {
items.Clear(); items.Clear();
items.Add(new T()); items.Add(new T
{
Version = EtagVersion.Empty
});
} }
public (T?, bool Valid) Get(long version) public (T?, bool Valid) Get(long version)

38
backend/tests/Squidex.Infrastructure.Tests/Commands/DomainObjectTests.cs

@ -32,7 +32,7 @@ namespace Squidex.Infrastructure.Commands
public void Should_instantiate() public void Should_instantiate()
{ {
Assert.Equal(EtagVersion.Empty, sut.Version); Assert.Equal(EtagVersion.Empty, sut.Version);
AssertSnapshot(sut.Snapshot, 0); AssertSnapshot(sut.Snapshot, 0, EtagVersion.Empty);
} }
[Fact] [Fact]
@ -53,7 +53,7 @@ namespace Squidex.Infrastructure.Commands
Assert.Equal(0, sut.Version); Assert.Equal(0, sut.Version);
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(sut.Snapshot, 4); AssertSnapshot(sut.Snapshot, 4, 0);
} }
[Fact] [Fact]
@ -78,7 +78,7 @@ namespace Squidex.Infrastructure.Commands
Assert.Equal(2, sut.Version); Assert.Equal(2, sut.Version);
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(sut.Snapshot, 4); AssertSnapshot(sut.Snapshot, 4, 2);
} }
[Fact] [Fact]
@ -117,7 +117,7 @@ namespace Squidex.Infrastructure.Commands
Assert.Equal(2, sut.Version); Assert.Equal(2, sut.Version);
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(sut.Snapshot, 4); AssertSnapshot(sut.Snapshot, 4, 2);
} }
[Fact] [Fact]
@ -154,7 +154,7 @@ namespace Squidex.Infrastructure.Commands
Assert.Equal(1, sut.Version); Assert.Equal(1, sut.Version);
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(sut.Snapshot, 8); AssertSnapshot(sut.Snapshot, 8, 1);
} }
[Fact] [Fact]
@ -175,7 +175,7 @@ namespace Squidex.Infrastructure.Commands
Assert.Equal(1, sut.Version); Assert.Equal(1, sut.Version);
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(sut.Snapshot, 8); AssertSnapshot(sut.Snapshot, 8, 1);
} }
[Fact] [Fact]
@ -201,7 +201,7 @@ namespace Squidex.Infrastructure.Commands
.MustHaveHappenedOnceExactly(); .MustHaveHappenedOnceExactly();
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(sut.Snapshot, 9); AssertSnapshot(sut.Snapshot, 9, 2);
} }
[Fact] [Fact]
@ -307,7 +307,7 @@ namespace Squidex.Infrastructure.Commands
Assert.Equal(0, sut.Version); Assert.Equal(0, sut.Version);
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(sut.Snapshot, 4); AssertSnapshot(sut.Snapshot, 4, 0);
} }
[Fact] [Fact]
@ -321,7 +321,7 @@ namespace Squidex.Infrastructure.Commands
await Assert.ThrowsAsync<InvalidOperationException>(() => sut.ExecuteAsync(new CreateAuto())); await Assert.ThrowsAsync<InvalidOperationException>(() => sut.ExecuteAsync(new CreateAuto()));
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(sut.Snapshot, 0); AssertSnapshot(sut.Snapshot, 0, EtagVersion.Empty);
} }
[Fact] [Fact]
@ -335,7 +335,7 @@ namespace Squidex.Infrastructure.Commands
await Assert.ThrowsAsync<InvalidOperationException>(() => sut.ExecuteAsync(new UpdateAuto())); await Assert.ThrowsAsync<InvalidOperationException>(() => sut.ExecuteAsync(new UpdateAuto()));
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(sut.Snapshot, 4); AssertSnapshot(sut.Snapshot, 4, 0);
} }
[Fact] [Fact]
@ -351,7 +351,7 @@ namespace Squidex.Infrastructure.Commands
await sut.ExecuteAsync(new DeletePermanent()); await sut.ExecuteAsync(new DeletePermanent());
AssertSnapshot(sut.Snapshot, 0, false); AssertSnapshot(sut.Snapshot, 0, EtagVersion.Empty, false);
A.CallTo(() => persistence.DeleteAsync()) A.CallTo(() => persistence.DeleteAsync())
.MustHaveHappened(); .MustHaveHappened();
@ -378,9 +378,9 @@ namespace Squidex.Infrastructure.Commands
var version_1 = await sut.GetSnapshotAsync(1); var version_1 = await sut.GetSnapshotAsync(1);
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(version_Empty, 0); AssertSnapshot(version_Empty, 0, EtagVersion.Empty);
AssertSnapshot(version_0, 3); AssertSnapshot(version_0, 3, 0);
AssertSnapshot(version_1, 4); AssertSnapshot(version_1, 4, 1);
A.CallTo(() => persistenceFactory.WithEventSourcing(typeof(MyDomainObject), id, A<HandleEvent>._)) A.CallTo(() => persistenceFactory.WithEventSourcing(typeof(MyDomainObject), id, A<HandleEvent>._))
.MustNotHaveHappened(); .MustNotHaveHappened();
@ -402,17 +402,17 @@ namespace Squidex.Infrastructure.Commands
var version_1 = await sut.GetSnapshotAsync(1); var version_1 = await sut.GetSnapshotAsync(1);
Assert.Empty(sut.GetUncomittedEvents()); Assert.Empty(sut.GetUncomittedEvents());
AssertSnapshot(version_Empty, 0); AssertSnapshot(version_Empty, 0, EtagVersion.Empty);
AssertSnapshot(version_0, 3); AssertSnapshot(version_0, 3, 0);
AssertSnapshot(version_1, 4); AssertSnapshot(version_1, 4, 1);
A.CallTo(() => persistenceFactory.WithEventSourcing(typeof(MyDomainObject), id, A<HandleEvent>._)) A.CallTo(() => persistenceFactory.WithEventSourcing(typeof(MyDomainObject), id, A<HandleEvent>._))
.MustHaveHappened(); .MustHaveHappened();
} }
private static void AssertSnapshot(MyDomainState state, int value, bool isDeleted = false) private static void AssertSnapshot(MyDomainState state, int value, long version, bool isDeleted = false)
{ {
Assert.Equal(new MyDomainState { Value = value, IsDeleted = isDeleted }, state); Assert.Equal(new MyDomainState { Value = value, Version = version, IsDeleted = isDeleted }, state);
} }
private void SetupDeleted() private void SetupDeleted()

2
backend/tests/Squidex.Infrastructure.Tests/TestHelpers/MyDomainState.cs

@ -16,6 +16,8 @@ namespace Squidex.Infrastructure.TestHelpers
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
public long Version { get; set; }
public long Value { get; set; } public long Value { get; set; }
public MyDomainState Apply(Envelope<IEvent> @event) public MyDomainState Apply(Envelope<IEvent> @event)

Loading…
Cancel
Save