Browse Source

Bugfixes for optimistic concurrency.

pull/1/head
Sebastian 9 years ago
parent
commit
ec8ba7540d
  1. 14
      src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs
  2. 2
      src/Squidex.Infrastructure/CQRS/CommonHeaders.cs
  3. 12
      src/Squidex.Infrastructure/CQRS/EnvelopeExtensions.cs
  4. 1
      src/Squidex.Infrastructure/CQRS/Events/EventReceiver.cs
  5. 10
      src/Squidex.Infrastructure/CQRS/Events/StoredEvent.cs
  6. 2
      src/Squidex.Read.MongoDb/Utils/EntityMapper.cs
  7. 2
      src/Squidex/app/features/content/pages/content/content-page.component.ts
  8. 8
      tests/Squidex.Infrastructure.Tests/CQRS/Commands/DefaultDomainObjectRepositoryTests.cs
  9. 11
      tests/Squidex.Infrastructure.Tests/CQRS/EnvelopeExtensionsTests.cs
  10. 1
      tests/Squidex.Infrastructure.Tests/CQRS/Events/EventDataFormatterTests.cs
  11. 6
      tests/Squidex.Infrastructure.Tests/CQRS/Events/EventReceiverTests.cs

14
src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs

@ -69,15 +69,17 @@ namespace Squidex.Infrastructure.MongoDb.EventStore
{
await Collection.Find(x => x.EventStream == streamName).ForEachAsync(commit =>
{
var position = commit.EventStreamOffset;
var eventNumber = commit.EventsOffset;
var eventStreamNumber = commit.EventStreamOffset;
foreach (var @event in commit.Events)
{
var eventData = SimpleMapper.Map(@event, new EventData());
eventNumber++;
eventStreamNumber++;
observer.OnNext(new StoredEvent(position, eventData));
var eventData = SimpleMapper.Map(@event, new EventData());
position++;
observer.OnNext(new StoredEvent(eventNumber, eventStreamNumber, eventData));
}
}, ct);
});
@ -92,16 +94,18 @@ namespace Squidex.Infrastructure.MongoDb.EventStore
await Collection.Find(x => x.EventsOffset >= commitOffset).SortBy(x => x.EventsOffset).ForEachAsync(commit =>
{
var eventNumber = commit.EventsOffset;
var eventStreamNumber = commit.EventStreamOffset;
foreach (var @event in commit.Events)
{
eventNumber++;
eventStreamNumber++;
if (eventNumber > lastReceivedEventNumber)
{
var eventData = SimpleMapper.Map(@event, new EventData());
observer.OnNext(new StoredEvent(eventNumber, eventData));
observer.OnNext(new StoredEvent(eventNumber, eventStreamNumber, eventData));
}
}
}, ct);

2
src/Squidex.Infrastructure/CQRS/CommonHeaders.cs

@ -18,6 +18,8 @@ namespace Squidex.Infrastructure.CQRS
public static readonly string EventNumber = "EventNumber";
public static readonly string EventStreamNumber = "EventStreamNumber";
public static readonly string Timestamp = "Timestamp";
public static readonly string Actor = "Actor";

12
src/Squidex.Infrastructure/CQRS/EnvelopeExtensions.cs

@ -26,6 +26,18 @@ namespace Squidex.Infrastructure.CQRS
return envelope;
}
public static long EventStreamNumber(this EnvelopeHeaders headers)
{
return headers[CommonHeaders.EventStreamNumber].ToInt32(CultureInfo.InvariantCulture);
}
public static Envelope<T> SetEventStreamNumber<T>(this Envelope<T> envelope, long value) where T : class
{
envelope.Headers.Set(CommonHeaders.EventStreamNumber, value);
return envelope;
}
public static Guid CommitId(this EnvelopeHeaders headers)
{
return headers[CommonHeaders.CommitId].ToGuid(CultureInfo.InvariantCulture);

1
src/Squidex.Infrastructure/CQRS/Events/EventReceiver.cs

@ -176,6 +176,7 @@ namespace Squidex.Infrastructure.CQRS.Events
var @event = formatter.Parse(storedEvent.Data);
@event.SetEventNumber(storedEvent.EventNumber);
@event.SetEventStreamNumber(storedEvent.EventStreamNumber);
return @event;
}

10
src/Squidex.Infrastructure/CQRS/Events/StoredEvent.cs

@ -11,6 +11,7 @@ namespace Squidex.Infrastructure.CQRS.Events
public sealed class StoredEvent
{
private readonly long eventNumber;
private readonly long eventStreamNumber;
private readonly EventData data;
public long EventNumber
@ -18,18 +19,23 @@ namespace Squidex.Infrastructure.CQRS.Events
get { return eventNumber; }
}
public long EventStreamNumber
{
get { return eventStreamNumber; }
}
public EventData Data
{
get { return data; }
}
public StoredEvent(long eventNumber, EventData data)
public StoredEvent(long eventNumber, long eventStreamNumber, EventData data)
{
Guard.NotNull(data, nameof(data));
this.data = data;
this.eventNumber = eventNumber;
this.eventStreamNumber = eventStreamNumber;
}
}
}

2
src/Squidex.Read.MongoDb/Utils/EntityMapper.cs

@ -62,7 +62,7 @@ namespace Squidex.Read.MongoDb.Utils
if (withVersion != null)
{
withVersion.Version = headers.EventNumber();
withVersion.Version = headers.EventStreamNumber();
}
}

2
src/Squidex/app/features/content/pages/content/content-page.component.ts

@ -39,7 +39,7 @@ import {
})
export class ContentPageComponent extends AppComponentBase implements OnDestroy, OnInit {
private messageSubscription: Subscription;
private version: Version;
private version: Version = new Version('');
public schema: SchemaDetailsDto;

8
tests/Squidex.Infrastructure.Tests/CQRS/Commands/DefaultDomainObjectRepositoryTests.cs

@ -90,8 +90,8 @@ namespace Squidex.Infrastructure.CQRS.Commands
var events = new[]
{
new StoredEvent(0, eventData1),
new StoredEvent(1, eventData2)
new StoredEvent(0, 0, eventData1),
new StoredEvent(1, 1, eventData2)
};
eventStore.Setup(x => x.GetEventsAsync(streamName)).Returns(events.ToObservable());
@ -115,8 +115,8 @@ namespace Squidex.Infrastructure.CQRS.Commands
var events = new[]
{
new StoredEvent(0, eventData1),
new StoredEvent(1, eventData2)
new StoredEvent(0, 0, eventData1),
new StoredEvent(1, 1, eventData2)
};
eventStore.Setup(x => x.GetEventsAsync(streamName)).Returns(events.ToObservable());

11
tests/Squidex.Infrastructure.Tests/CQRS/EnvelopeExtensionsTests.cs

@ -72,5 +72,16 @@ namespace Squidex.Infrastructure.CQRS
Assert.Equal(eventNumber, sut.Headers.EventNumber());
Assert.Equal(eventNumber, sut.Headers["EventNumber"].ToInt32(culture));
}
[Fact]
public void Should_set_and_get_event_stream_number()
{
const int eventStreamNumber = 123;
sut.SetEventStreamNumber(eventStreamNumber);
Assert.Equal(eventStreamNumber, sut.Headers.EventStreamNumber());
Assert.Equal(eventStreamNumber, sut.Headers["EventStreamNumber"].ToInt32(culture));
}
}
}

1
tests/Squidex.Infrastructure.Tests/CQRS/Events/EventDataFormatterTests.cs

@ -42,6 +42,7 @@ namespace Squidex.Infrastructure.CQRS.Events
inputEvent.SetCommitId(commitId);
inputEvent.SetEventId(Guid.NewGuid());
inputEvent.SetEventNumber(1);
inputEvent.SetEventStreamNumber(1);
inputEvent.SetTimestamp(SystemClock.Instance.GetCurrentInstant());
var sut = new EventDataFormatter(typeNameRegistry, serializerSettings);

6
tests/Squidex.Infrastructure.Tests/CQRS/Events/EventReceiverTests.cs

@ -81,9 +81,9 @@ namespace Squidex.Infrastructure.CQRS.Events
{
events = new[]
{
new StoredEvent(3, eventData1),
new StoredEvent(4, eventData2),
new StoredEvent(4, eventData3)
new StoredEvent(3, 3, eventData1),
new StoredEvent(4, 4, eventData2),
new StoredEvent(4, 4, eventData3)
};
consumerName = eventConsumer.Object.GetType().Name;

Loading…
Cancel
Save