87 lines
3.1 KiB
C#
87 lines
3.1 KiB
C#
using System;
|
|
using SubscriptionStatusEnum = Svrnty.CQRS.Events.Abstractions.Subscriptions.SubscriptionStatus;
|
|
using Svrnty.CQRS.Events.Abstractions.Subscriptions;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Svrnty.CQRS.Events.Abstractions;
|
|
using Svrnty.CQRS.Events.Abstractions.Models;
|
|
|
|
namespace Svrnty.CQRS.Events.Storage;
|
|
|
|
/// <summary>
|
|
/// In-memory implementation of ISubscriptionStore for testing and development.
|
|
/// Thread-safe but data is lost on application restart.
|
|
/// </summary>
|
|
public sealed class InMemorySubscriptionStore : ISubscriptionStore
|
|
{
|
|
private readonly ConcurrentDictionary<string, EventSubscription> _subscriptions = new();
|
|
|
|
public Task CreateAsync(EventSubscription subscription, CancellationToken cancellationToken = default)
|
|
{
|
|
_subscriptions.TryAdd(subscription.SubscriptionId, subscription);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task<EventSubscription?> GetByIdAsync(string subscriptionId, CancellationToken cancellationToken = default)
|
|
{
|
|
_subscriptions.TryGetValue(subscriptionId, out var subscription);
|
|
return Task.FromResult(subscription);
|
|
}
|
|
|
|
public Task<List<EventSubscription>> GetBySubscriberIdAsync(string subscriberId, CancellationToken cancellationToken = default)
|
|
{
|
|
var result = _subscriptions.Values
|
|
.Where(s => s.SubscriberId == subscriberId)
|
|
.ToList();
|
|
|
|
return Task.FromResult(result);
|
|
}
|
|
|
|
public Task<List<EventSubscription>> FindByCorrelationIdAsync(string correlationId, CancellationToken cancellationToken = default)
|
|
{
|
|
var result = _subscriptions.Values
|
|
.Where(s => s.CorrelationId == correlationId)
|
|
.Where(s => s.Status == SubscriptionStatus.Active && !s.IsExpired)
|
|
.ToList();
|
|
|
|
return Task.FromResult(result);
|
|
}
|
|
|
|
public Task UpdateAsync(EventSubscription subscription, CancellationToken cancellationToken = default)
|
|
{
|
|
// In-memory store: the object is already updated by reference
|
|
// Just ensure it's in the dictionary
|
|
_subscriptions.TryAdd(subscription.SubscriptionId, subscription);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task DeleteAsync(string subscriptionId, CancellationToken cancellationToken = default)
|
|
{
|
|
_subscriptions.TryRemove(subscriptionId, out _);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task<int> DeleteOldSubscriptionsAsync(DateTimeOffset olderThan, CancellationToken cancellationToken = default)
|
|
{
|
|
var toDelete = _subscriptions.Values
|
|
.Where(s => s.CompletedAt.HasValue && s.CompletedAt.Value < olderThan)
|
|
.Where(s => s.Status != SubscriptionStatus.Active)
|
|
.Select(s => s.SubscriptionId)
|
|
.ToList();
|
|
|
|
int deletedCount = 0;
|
|
foreach (var subscriptionId in toDelete)
|
|
{
|
|
if (_subscriptions.TryRemove(subscriptionId, out _))
|
|
{
|
|
deletedCount++;
|
|
}
|
|
}
|
|
|
|
return Task.FromResult(deletedCount);
|
|
}
|
|
}
|