Families.Web 1.0.0.0
사진, 동영상, 글, 댓글과 반응을 가족끼리만 공유하는 비공개 앨범·타임라인 서비스입니다.
로딩중...
검색중...
일치하는것 없음
GhostAccountCleanupService.cs
이 파일의 문서화 페이지로 가기
1using Microsoft.Extensions.Hosting;
2using Microsoft.Extensions.Logging;
3
5
14public sealed class GhostAccountCleanupService : BackgroundService
15{
24 private readonly IFamilyTenantStore _tenants;
33 private readonly IPostStore _posts;
42 private readonly ILogger<GhostAccountCleanupService> _logger;
51 private static readonly TimeSpan Interval = TimeSpan.FromHours(1);
60 private static readonly TimeSpan GracePeriod = TimeSpan.FromHours(24);
61
95 ILogger<GhostAccountCleanupService> logger)
96 {
97 _tenants = tenants;
98 _posts = posts;
99 _logger = logger;
100 }
101
126 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
127 {
128 while (!stoppingToken.IsCancellationRequested)
129 {
130 await Task.Delay(Interval, stoppingToken).ConfigureAwait(false);
131 await RunCleanupAsync(stoppingToken).ConfigureAwait(false);
132 }
133 }
134
159 private async Task RunCleanupAsync(CancellationToken ct)
160 {
161 try
162 {
163 var all = await _tenants.GetAllAsync(ct).ConfigureAwait(false);
164 var cutoff = DateTime.Now - GracePeriod;
165
166 foreach (var t in all)
167 {
168 if (t.CreatedAt > cutoff) continue;
169
170 var postList = await _posts.GetAllAsync(t.Slug, ct).ConfigureAwait(false);
171 if (postList.Count > 0) continue;
172
173 await _tenants.DeleteAsync(t.Slug, ct).ConfigureAwait(false);
174 _logger.LogInformation("고스트 계정 자동 삭제: {Slug} (생성: {CreatedAt:g}, 포스트 0개)", t.Slug, t.CreatedAt);
175 }
176 }
177 catch (Exception ex) when (ex is not OperationCanceledException)
178 {
179 _logger.LogError(ex, "고스트 계정 정리 중 오류 발생");
180 }
181 }
182}
override async Task ExecuteAsync(CancellationToken stoppingToken)
GhostAccountCleanupService(IFamilyTenantStore tenants, IPostStore posts, ILogger< GhostAccountCleanupService > logger)
readonly ILogger< GhostAccountCleanupService > _logger