dotnet-cqrs/Svrnty.CQRS.Events/Subscriptions/InMemorySubscriptionStore.cs

109 lines
3.6 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Svrnty.CQRS.Events.Abstractions.Subscriptions;
namespace Svrnty.CQRS.Events.Subscriptions;
/// <summary>
/// In-memory implementation of subscription store for development and testing.
/// </summary>
public sealed class InMemorySubscriptionStore : IPersistentSubscriptionStore
{
private readonly ConcurrentDictionary<string, PersistentSubscription> _subscriptions = new();
public Task<PersistentSubscription> CreateAsync(
PersistentSubscription subscription,
CancellationToken cancellationToken = default)
{
if (!_subscriptions.TryAdd(subscription.Id, subscription))
{
throw new InvalidOperationException($"Subscription with ID {subscription.Id} already exists");
}
return Task.FromResult(subscription);
}
public Task<PersistentSubscription?> GetByIdAsync(
string id,
CancellationToken cancellationToken = default)
{
_subscriptions.TryGetValue(id, out var subscription);
return Task.FromResult(subscription);
}
public Task<IReadOnlyList<PersistentSubscription>> GetBySubscriberIdAsync(
string subscriberId,
CancellationToken cancellationToken = default)
{
var subscriptions = _subscriptions.Values
.Where(s => s.SubscriberId == subscriberId)
.ToList();
return Task.FromResult<IReadOnlyList<PersistentSubscription>>(subscriptions);
}
public Task<IReadOnlyList<PersistentSubscription>> GetByCorrelationIdAsync(
string correlationId,
CancellationToken cancellationToken = default)
{
var subscriptions = _subscriptions.Values
.Where(s => s.CorrelationId == correlationId)
.ToList();
return Task.FromResult<IReadOnlyList<PersistentSubscription>>(subscriptions);
}
public Task<IReadOnlyList<PersistentSubscription>> GetByStatusAsync(
SubscriptionStatus status,
CancellationToken cancellationToken = default)
{
var subscriptions = _subscriptions.Values
.Where(s => s.Status == status)
.ToList();
return Task.FromResult<IReadOnlyList<PersistentSubscription>>(subscriptions);
}
public Task<IReadOnlyList<PersistentSubscription>> GetByConnectionIdAsync(
string connectionId,
CancellationToken cancellationToken = default)
{
var subscriptions = _subscriptions.Values
.Where(s => s.ConnectionId == connectionId)
.ToList();
return Task.FromResult<IReadOnlyList<PersistentSubscription>>(subscriptions);
}
public Task UpdateAsync(
PersistentSubscription subscription,
CancellationToken cancellationToken = default)
{
_subscriptions[subscription.Id] = subscription;
return Task.CompletedTask;
}
public Task DeleteAsync(
string id,
CancellationToken cancellationToken = default)
{
_subscriptions.TryRemove(id, out _);
return Task.CompletedTask;
}
public Task<IReadOnlyList<PersistentSubscription>> GetExpiredSubscriptionsAsync(
CancellationToken cancellationToken = default)
{
var now = DateTimeOffset.UtcNow;
var expired = _subscriptions.Values
.Where(s => s.ExpiresAt.HasValue && s.ExpiresAt.Value < now && s.Status == SubscriptionStatus.Active)
.ToList();
return Task.FromResult<IReadOnlyList<PersistentSubscription>>(expired);
}
}