AcaMate_API/Program/Services/V1/InMemoryPushQueue.cs

60 lines
1.9 KiB
C#

using System.Collections.Concurrent;
using Back.Program.Models.Entities;
namespace Back.Program.Services.V1
{
public interface IPushQueue
{
void Enqueue(PushData pushData);
Task<PushData> DequeueAsync(CancellationToken cancellationToken);
}
public class InMemoryPushQueue: IPushQueue
{
private readonly ConcurrentQueue<PushData> _queue = new ConcurrentQueue<PushData>();
private readonly SemaphoreSlim _signal = new SemaphoreSlim(0);
public void Enqueue(PushData pushData)
{
if( pushData is null )
throw new ArgumentNullException(nameof(pushData));
_queue.Enqueue(pushData);
_signal.Release();
}
public async Task<PushData> DequeueAsync(CancellationToken cancellationToken)
{
await _signal.WaitAsync(cancellationToken);
_queue.TryDequeue(out var pushData);
return pushData;
}
}
public class PushBackgroundService : BackgroundService
{
private readonly IPushQueue _queue;
private readonly IApnsPushService _pushService;
public PushBackgroundService(IPushQueue queue, IApnsPushService pushService)
{
_queue = queue;
_pushService = pushService;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var pushData = await _queue.DequeueAsync(stoppingToken);
try
{
await _pushService.SendPushNotificationAsync(pushData.pushToken, pushData.payload);
}
catch (Exception ex)
{
Console.WriteLine($"푸시 전송 실패: {ex.Message}");
}
}
}
}
}