Synchronization manager.

This commit is contained in:
Burak Kaan Köse
2025-10-04 23:10:07 +02:00
parent 3b1eff1702
commit 9623c2e6d2
17 changed files with 709 additions and 352 deletions
@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Authentication;
using Wino.Core.Domain.Models.Connectivity;
using Wino.Core.Domain.Models.Synchronization;
namespace Wino.Core.Domain.Interfaces;
/// <summary>
/// Interface for the singleton synchronization manager that handles synchronizer instances and operations.
/// </summary>
public interface ISynchronizationManager
{
/// <summary>
/// Initializes the SynchronizationManager with required dependencies.
/// </summary>
Task InitializeAsync(ISynchronizerFactory synchronizerFactory,
IImapTestService imapTestService,
IAccountService accountService,
IAuthenticationProvider authenticationProvider);
/// <summary>
/// Tests IMAP server connectivity for the given server information.
/// </summary>
Task<ImapConnectivityTestResults> TestImapConnectivityAsync(CustomServerInformation serverInformation, bool allowSSLHandshake);
/// <summary>
/// Starts a new mail synchronization for the given account.
/// </summary>
Task<MailSynchronizationResult> SynchronizeMailAsync(MailSynchronizationOptions options,
CancellationToken cancellationToken = default);
/// <summary>
/// Checks if there is an ongoing synchronization for the given account.
/// </summary>
bool IsAccountSynchronizing(Guid accountId);
/// <summary>
/// Queues a mail action request to the corresponding account's synchronizer.
/// </summary>
Task QueueRequestAsync(IRequestBase request, Guid accountId);
/// <summary>
/// Handles folder synchronization for the given account.
/// </summary>
Task<MailSynchronizationResult> SynchronizeFoldersAsync(Guid accountId,
CancellationToken cancellationToken = default);
/// <summary>
/// Handles alias synchronization for the given account.
/// </summary>
Task<MailSynchronizationResult> SynchronizeAliasesAsync(Guid accountId,
CancellationToken cancellationToken = default);
/// <summary>
/// Handles profile synchronization for the given account.
/// </summary>
Task<MailSynchronizationResult> SynchronizeProfileAsync(Guid accountId,
CancellationToken cancellationToken = default);
/// <summary>
/// Downloads a MIME message for the given mail item.
/// </summary>
Task<string> DownloadMimeMessageAsync(MailCopy mailItem, Guid accountId,
CancellationToken cancellationToken = default);
/// <summary>
/// Creates a new synchronizer for a newly added account.
/// </summary>
Task<IWinoSynchronizerBase> CreateSynchronizerForAccountAsync(MailAccount account);
/// <summary>
/// Destroys the synchronizer for the given account.
/// </summary>
Task DestroySynchronizerAsync(Guid accountId);
/// <summary>
/// Gets all cached synchronizers.
/// </summary>
IEnumerable<IWinoSynchronizerBase> GetAllSynchronizers();
/// <summary>
/// Gets a synchronizer for the given account ID.
/// </summary>
Task<IWinoSynchronizerBase> GetSynchronizerAsync(Guid accountId);
/// <summary>
/// Handles OAuth authentication for the specified provider.
/// </summary>
Task<TokenInformationEx> HandleAuthorizationAsync(MailProviderType providerType,
MailAccount account = null,
bool proposeCopyAuthorizationURL = false);
}
@@ -1,106 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Wino.Core.Domain.Interfaces;
/// <summary>
/// Simple wrapper class to maintain compatibility with the original WinoServerResponse structure.
/// </summary>
/// <typeparam name="T">Type of the expected response.</typeparam>
public class WinoServerResponse<T>
{
public bool IsSuccess { get; set; }
public string Message { get; set; }
public T Data { get; set; }
public static WinoServerResponse<T> CreateSuccessResponse(T data)
{
return new WinoServerResponse<T>
{
IsSuccess = true,
Data = data
};
}
public static WinoServerResponse<T> CreateErrorResponse(string message)
{
return new WinoServerResponse<T>
{
IsSuccess = false,
Message = message
};
}
public void ThrowIfFailed()
{
if (!IsSuccess)
throw new InvalidOperationException(Message);
}
}
/// <summary>
/// Connection status enum to maintain compatibility.
/// </summary>
public enum WinoServerConnectionStatus
{
None,
Connecting,
Connected,
Disconnected,
Failed
}
public interface IWinoServerConnectionManager
{
/// <summary>
/// When the connection status changes, this event will be triggered.
/// </summary>
event EventHandler<WinoServerConnectionStatus> StatusChanged;
/// <summary>
/// Gets the connection status.
/// </summary>
WinoServerConnectionStatus Status { get; }
/// <summary>
/// Launches Full Trust process (Wino Server) and awaits connection completion.
/// If connection is not established in 10 seconds, it will return false.
/// If the server process is already running, it'll connect to existing one.
/// If the server process is not running, it'll be launched and connection establishment is awaited.
/// </summary>
/// <returns>Whether connection is established or not.</returns>
Task<bool> ConnectAsync();
/// <summary>
/// Queues a new user request to be processed by Wino Server.
/// Healthy connection must present before calling this method.
/// </summary>
/// <param name="request">Request to queue for synchronizer in the server.</param>
/// <param name="accountId">Account id to queueu request for.</param>
Task QueueRequestAsync(IRequestBase request, Guid accountId);
/// <summary>
/// Returns response from server for the given request.
/// </summary>
/// <typeparam name="TResponse">Response type.</typeparam>
/// <typeparam name="TRequestType">Request type.</typeparam>
/// <param name="clientMessage">Request type.</param>
/// <returns>Response received from the server for the given TResponse type.</returns>
Task<WinoServerResponse<TResponse>> GetResponseAsync<TResponse, TRequestType>(TRequestType clientMessage, CancellationToken cancellationToken = default) where TRequestType : IClientMessage;
/// <summary>
/// Handle for connecting to the server.
/// If the server is already running, it'll connect to existing one.
/// Callers can await this handle to wait for connection establishment.
/// </summary>
TaskCompletionSource<bool> ConnectingHandle { get; }
}
public interface IWinoServerConnectionManager<TAppServiceConnection> : IWinoServerConnectionManager, IInitializeAsync
{
/// <summary>
/// Existing connection handle to the server of TAppServiceConnection type.
/// </summary>
TAppServiceConnection Connection { get; set; }
}