using System.Collections.Concurrent; namespace DysonNetwork.Sphere.Storage; public interface IFlushHandler { Task FlushAsync(IReadOnlyList items); } public class FlushBufferService { private readonly Dictionary _buffers = new(); private readonly Lock _lockObject = new(); private ConcurrentQueue _GetOrCreateBuffer() { var type = typeof(T); lock (_lockObject) { if (!_buffers.TryGetValue(type, out var buffer)) { buffer = new ConcurrentQueue(); _buffers[type] = buffer; } return (ConcurrentQueue)buffer; } } public void Enqueue(T item) { var buffer = _GetOrCreateBuffer(); buffer.Enqueue(item); } public async Task FlushAsync(IFlushHandler handler) { var buffer = _GetOrCreateBuffer(); var workingQueue = new List(); while (buffer.TryDequeue(out var item)) { workingQueue.Add(item); } if (workingQueue.Count == 0) return; try { await handler.FlushAsync(workingQueue); } catch (Exception) { // If flush fails, re-queue the items foreach (var item in workingQueue) buffer.Enqueue(item); throw; } } public int GetPendingCount() { var buffer = _GetOrCreateBuffer(); return buffer.Count; } }