Headless CMS and Content Managment Hub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

91 lines
2.9 KiB

// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using EventStore.Client;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Tasks;
namespace Squidex.Infrastructure.EventSourcing;
internal sealed class GetEventStoreSubscription : IEventSubscription
{
private readonly CancellationTokenSource cts = new CancellationTokenSource();
private StreamSubscription subscription;
public GetEventStoreSubscription(
IEventSubscriber<StoredEvent> eventSubscriber,
EventStoreClient client,
EventStoreProjectionClient projectionClient,
IJsonSerializer serializer,
string? position,
string? prefix,
StreamFilter filter)
{
#pragma warning disable MA0134 // Observe result of async calls
Task.Run(async () =>
{
var ct = cts.Token;
var streamName = await projectionClient.CreateProjectionAsync(filter);
async Task OnEvent(StreamSubscription subscription, ResolvedEvent @event,
CancellationToken ct)
{
var storedEvent = Formatter.Read(@event, prefix, serializer);
await eventSubscriber.OnNextAsync(this, storedEvent);
}
void OnError(StreamSubscription subscription, SubscriptionDroppedReason reason, Exception? ex)
{
if (reason != SubscriptionDroppedReason.Disposed &&
reason != SubscriptionDroppedReason.SubscriberError)
{
ex ??= new InvalidOperationException($"Subscription closed with reason {reason}.");
eventSubscriber.OnErrorAsync(this, ex).AsTask().Forget();
}
}
if (!string.IsNullOrWhiteSpace(position))
{
var from = FromStream.After(position.ToPosition(true));
subscription = await client.SubscribeToStreamAsync(streamName, from,
OnEvent, true,
OnError,
cancellationToken: ct);
}
else
{
var from = FromStream.Start;
subscription = await client.SubscribeToStreamAsync(streamName, from,
OnEvent, true,
OnError,
cancellationToken: ct);
}
}, cts.Token);
#pragma warning restore MA0134 // Observe result of async calls
}
public void Dispose()
{
subscription?.Dispose();
cts.Cancel();
}
public ValueTask CompleteAsync()
{
return default;
}
public void WakeUp()
{
}
}