Listening imap inbox changes with idle client.

This commit is contained in:
Burak Kaan Köse
2024-08-13 14:12:54 +02:00
parent 5912adff93
commit ed6a7d71b4
5 changed files with 182 additions and 52 deletions

View File

@@ -13,6 +13,7 @@ using Wino.Core.Domain.Models.Requests;
using Wino.Core.Domain.Models.Synchronization;
using Wino.Core.Integration.Json;
using Wino.Core.Services;
using Wino.Core.Synchronizers;
using Wino.Messaging;
using Wino.Messaging.Client.Authorization;
using Wino.Messaging.Enums;
@@ -40,7 +41,8 @@ namespace Wino.Server
IRecipient<AccountSynchronizerStateChanged>,
IRecipient<RefreshUnreadCountsMessage>,
IRecipient<ServerTerminationModeChanged>,
IRecipient<AccountSynchronizationProgressUpdatedMessage>
IRecipient<AccountSynchronizationProgressUpdatedMessage>,
IRecipient<NewSynchronizationRequested>
{
private readonly System.Timers.Timer _timer;
private static object connectionLock = new object();
@@ -57,6 +59,8 @@ namespace Wino.Server
TypeInfoResolver = new ServerRequestTypeInfoResolver()
};
private Task imapIdleTask = null;
public ServerContext(IDatabaseService databaseService,
IApplicationConfiguration applicationFolderConfiguration,
ISynchronizerFactory synchronizerFactory,
@@ -171,7 +175,11 @@ namespace Wino.Server
AppServiceConnectionStatus status = await connection.OpenAsync();
if (status != AppServiceConnectionStatus.Success)
if (status == AppServiceConnectionStatus.Success)
{
imapIdleTask = RegisterImapSynchronizerChangesAsync();
}
else
{
Log.Error("Opening server connection failed. Status: {status}", status);
@@ -179,6 +187,53 @@ namespace Wino.Server
}
}
private async Task PerformForAllImapSynchronizers(Action<ImapSynchronizer> action)
{
var allAccounts = await _accountService.GetAccountsAsync().ConfigureAwait(false);
var imapAccounts = allAccounts.FindAll(a => a.ProviderType == MailProviderType.IMAP4);
foreach (var account in imapAccounts)
{
var synchronizer = await _synchronizerFactory.GetAccountSynchronizerAsync(account.Id).ConfigureAwait(false);
if (synchronizer == null) continue;
if (synchronizer is not ImapSynchronizer accountImapSynchronizer)
{
Log.Warning("Account '{Name}' has IMAP4 type but synchronizer is not ImapSynchronizer.", account.Name);
continue;
}
action(accountImapSynchronizer);
}
}
/// <summary>
/// Hooks all ImapSynchronizer instances to listen for changes like new mail, folder rename etc.
/// </summary>
private Task RegisterImapSynchronizerChangesAsync()
=> PerformForAllImapSynchronizers(async accountImapSynchronizer =>
{
// First make sure that listening is stopped.
await accountImapSynchronizer.StopInboxListeningAsync();
var startListeningTask = accountImapSynchronizer.StartInboxListeningAsync();
await Task.Delay(10000); // Wait for 10 seconds.
if (startListeningTask.Exception == null)
{
Log.Information("IMAP change listening started for account '{Name}'.", accountImapSynchronizer.Account.Name);
}
});
public Task DisposeActiveImapConnectionsAsync()
=> PerformForAllImapSynchronizers(async accountImapSynchronizer =>
{
await accountImapSynchronizer.KillAsync();
});
/// <summary>
/// Disposes current connection to UWP app service.
/// </summary>
@@ -337,5 +392,10 @@ namespace Wino.Server
App.Current.ChangeNotifyIconVisiblity(isServerTrayIconVisible);
}
public async void Receive(NewSynchronizationRequested message)
{
await ExecuteServerMessageSafeAsync(null, message);
}
}
}

View File

@@ -26,6 +26,8 @@ namespace Wino.Server
[RelayCommand]
public Task LaunchWinoAsync()
{
// Stop listening active imap synchronizer changes and disconnect gracefully.
return Context.DisposeActiveImapConnectionsAsync();
//var opt = new SynchronizationOptions()
//{
// Type = Wino.Core.Domain.Enums.SynchronizationType.Full,
@@ -37,7 +39,7 @@ namespace Wino.Server
// return Task.CompletedTask;
return Launcher.LaunchUriAsync(new Uri($"{App.WinoMailLaunchProtocol}:")).AsTask();
// return Launcher.LaunchUriAsync(new Uri($"{App.WinoMailLaunchProtocol}:")).AsTask();
//await _notificationBuilder.CreateNotificationsAsync(Guid.Empty, new List<IMailItem>()
//{
// new MailCopy(){ UniqueId = Guid.Parse("8f25d2a0-4448-4fee-96a9-c9b25a19e866")}
@@ -71,6 +73,9 @@ namespace Wino.Server
}
}
// Stop listening active imap synchronizer changes and disconnect gracefully.
await Context.DisposeActiveImapConnectionsAsync();
Application.Current.Shutdown();
}