diff --git a/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs b/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs index 834cc8f..f365356 100644 --- a/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs +++ b/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs @@ -29,5 +29,13 @@ public interface IImapEmailService long uid, string folder = "INBOX", CancellationToken cancellationToken = default); + + /// + /// Gets the last IMAP sync date for the specified account and folder. + /// + /// + /// + /// + DateTime? GetLastImapSyncDate(int accountId, string folder = "INBOX"); } #endif \ No newline at end of file diff --git a/src/infrastructure/DigitalData.MessagingService.Infrastructure/Services/LimilabsImapEmailService.cs b/src/infrastructure/DigitalData.MessagingService.Infrastructure/Services/LimilabsImapEmailService.cs index 41a3263..a9a6f55 100644 --- a/src/infrastructure/DigitalData.MessagingService.Infrastructure/Services/LimilabsImapEmailService.cs +++ b/src/infrastructure/DigitalData.MessagingService.Infrastructure/Services/LimilabsImapEmailService.cs @@ -5,8 +5,8 @@ using DigitalData.MessagingService.Domain.Entities; using DigitalData.MessagingService.Infrastructure.Services.Extensions; using Limilabs.Client.IMAP; using Limilabs.Mail; -using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; +using System.Collections.Concurrent; using System.Text; namespace DigitalData.MessagingService.Infrastructure.Services; @@ -15,7 +15,7 @@ namespace DigitalData.MessagingService.Infrastructure.Services; /// IMAP email service using Limilabs Mail.dll. /// Opens a fresh connection per call — stateless and thread-safe. /// -public class LimilabsImapEmailService(ILogger Logger, IRepository Repository, IMemoryCache Cache) : IImapEmailService +public class LimilabsImapEmailService(ILogger Logger, IRepository Repository) : IImapEmailService { private static readonly string CacheKeyPrefix = Guid.NewGuid().ToString(); @@ -34,7 +34,7 @@ public class LimilabsImapEmailService(ILogger Logger, // Server-side: only date range; all other filters are applied in-process after cache retrieval List criterions = []; - var since = Cache.GetLastImapSyncDate(account.Id, folder); + var since = GetLastImapSyncDate(account.Id, folder); if (since is not null && since != default) criterions.Add(Expression.SentSince(since.Value)); @@ -112,7 +112,7 @@ public class LimilabsImapEmailService(ILogger Logger, emails.Add(email); - Cache.SetLastImapSyncDate(account.Id, folder, operationStartTime); + SetLastImapSyncDate(account.Id, folder, operationStartTime); } catch (Exception ex) { @@ -136,11 +136,7 @@ public class LimilabsImapEmailService(ILogger Logger, } } - public async Task MarkAsSeenAsync( - EmailAccount account, - long uid, - string folder = "INBOX", - CancellationToken cancel = default) + public async Task MarkAsSeenAsync(EmailAccount account, long uid, string folder = "INBOX", CancellationToken cancel = default) { using var imap = await OpenAsync(account, folder, cancel); try @@ -173,4 +169,21 @@ public class LimilabsImapEmailService(ILogger Logger, return imap; } + + #region IMAP Last Sync Date Cache + private readonly ConcurrentDictionary _cache = new(); + + private record ImapCacheKey(int AccountId, string Folder); + + public DateTime? GetLastImapSyncDate(int accountId, string folder = "INBOX") + { + return _cache.GetValueOrDefault(new ImapCacheKey(accountId, folder)); + } + + private void SetLastImapSyncDate(int accountId, string folder, DateTime date) + { + var key = new ImapCacheKey(accountId, folder); + _cache[key] = date; + } + #endregion }