| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- using Application.Abstractions.Cache;
- using Application.Abstractions.YouTube;
- using Microsoft.Extensions.Hosting;
- using Microsoft.Extensions.Logging;
- using StackExchange.Redis;
- namespace Infrastructure.YouTube;
- /// <summary>
- /// PubSubHubbub 구독 자동 갱신 BackgroundService
- /// 구독은 약 10일 후 만료 → 7일마다 재구독
- /// </summary>
- internal sealed class YouTubePubSubRenewalService(
- IYouTubePubSubService pubSubService,
- IConnectionMultiplexer redis,
- ILogger<YouTubePubSubRenewalService> logger
- ) : BackgroundService
- {
- private static readonly TimeSpan RenewalInterval = TimeSpan.FromDays(7);
- private static readonly TimeSpan InitialDelay = TimeSpan.FromSeconds(30);
- protected override async Task ExecuteAsync(CancellationToken stoppingToken)
- {
- await Task.Delay(InitialDelay, stoppingToken);
- logger.LogInformation("[PubSub Renewal] 서비스 시작 — 갱신 주기: {Interval}일", RenewalInterval.TotalDays);
- while (!stoppingToken.IsCancellationRequested)
- {
- try
- {
- await RenewAllSubscriptionsAsync(stoppingToken);
- }
- catch (Exception ex)
- {
- logger.LogError(ex, "[PubSub Renewal] 구독 갱신 중 오류");
- }
- await Task.Delay(RenewalInterval, stoppingToken);
- }
- }
- private async Task RenewAllSubscriptionsAsync(CancellationToken ct)
- {
- var db = redis.GetDatabase();
- var channelIds = await db.SetMembersAsync(CacheKeys.YouTubePubSubChannels);
- if (channelIds.Length == 0)
- {
- logger.LogInformation("[PubSub Renewal] 구독 중인 채널 없음");
- return;
- }
- var renewed = 0;
- foreach (var channelId in channelIds)
- {
- var id = channelId.ToString();
- var success = await pubSubService.SubscribeAsync(id, ct);
- if (success)
- {
- renewed++;
- }
- // 요청 간 1초 간격
- await Task.Delay(TimeSpan.FromSeconds(1), ct);
- }
- logger.LogInformation("[PubSub Renewal] {Renewed}/{Total} 채널 구독 갱신 완료", renewed, channelIds.Length);
- }
- }
|