YouTubePubSubRenewalService.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using Application.Abstractions.YouTube;
  2. using Microsoft.Extensions.Hosting;
  3. using Microsoft.Extensions.Logging;
  4. namespace Infrastructure.YouTube;
  5. /// <summary>
  6. /// PubSubHubbub 구독 자동 갱신 BackgroundService
  7. /// 구독은 약 10일 후 만료 → 7일마다 재구독
  8. /// </summary>
  9. internal sealed class YouTubePubSubRenewalService(
  10. IYouTubePubSubService pubSubService,
  11. ILogger<YouTubePubSubRenewalService> logger
  12. ) : BackgroundService
  13. {
  14. private static readonly TimeSpan RenewalInterval = TimeSpan.FromDays(7);
  15. private static readonly TimeSpan InitialDelay = TimeSpan.FromSeconds(30);
  16. protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  17. {
  18. await Task.Delay(InitialDelay, stoppingToken);
  19. logger.LogInformation("[PubSub Renewal] 서비스 시작 — 갱신 주기: {Interval}일", RenewalInterval.TotalDays);
  20. while (!stoppingToken.IsCancellationRequested)
  21. {
  22. try
  23. {
  24. await RenewAllSubscriptionsAsync(stoppingToken);
  25. }
  26. catch (Exception ex)
  27. {
  28. logger.LogError(ex, "[PubSub Renewal] 구독 갱신 중 오류");
  29. }
  30. await Task.Delay(RenewalInterval, stoppingToken);
  31. }
  32. }
  33. private async Task RenewAllSubscriptionsAsync(CancellationToken ct)
  34. {
  35. var channelIds = await pubSubService.GetSubscribedChannelIdsAsync(ct);
  36. if (channelIds.Count == 0)
  37. {
  38. logger.LogInformation("[PubSub Renewal] 구독 중인 채널 없음");
  39. return;
  40. }
  41. var renewed = 0;
  42. foreach (var id in channelIds)
  43. {
  44. var success = await pubSubService.SubscribeAsync(id, ct);
  45. if (success)
  46. {
  47. renewed++;
  48. }
  49. // 요청 간 1초 간격
  50. await Task.Delay(TimeSpan.FromSeconds(1), ct);
  51. }
  52. logger.LogInformation("[PubSub Renewal] {Renewed}/{Total} 채널 구독 갱신 완료", renewed, channelIds.Count);
  53. }
  54. }