From 1193d76838268563455407fc66ca2a4a2939c051 Mon Sep 17 00:00:00 2001 From: Mia Winter Date: Mon, 8 Apr 2024 11:46:54 +0200 Subject: [PATCH] Added Smtp reconnect on connection loss --- Wave/Services/IEmailService.cs | 4 ++-- Wave/Services/SmtpEmailService.cs | 33 ++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Wave/Services/IEmailService.cs b/Wave/Services/IEmailService.cs index 4f823d4..0b3cd06 100644 --- a/Wave/Services/IEmailService.cs +++ b/Wave/Services/IEmailService.cs @@ -4,7 +4,7 @@ public interface IEmailService : IAsyncDisposable { ValueTask ConnectAsync(CancellationToken cancellation); ValueTask DisconnectAsync(CancellationToken cancellation); - ValueTask SendEmailAsync(IEmail email); + ValueTask SendEmailAsync(IEmail email, CancellationToken cancellation = default); } public sealed class NoOpEmailService : IEmailService { @@ -12,5 +12,5 @@ public sealed class NoOpEmailService : IEmailService { public ValueTask ConnectAsync(CancellationToken cancellation) => ValueTask.CompletedTask; public ValueTask DisconnectAsync(CancellationToken cancellation) => ValueTask.CompletedTask; - public ValueTask SendEmailAsync(IEmail email) => ValueTask.CompletedTask; + public ValueTask SendEmailAsync(IEmail email, CancellationToken cancellation = default) => ValueTask.CompletedTask; } \ No newline at end of file diff --git a/Wave/Services/SmtpEmailService.cs b/Wave/Services/SmtpEmailService.cs index 0138cf8..6c3241e 100644 --- a/Wave/Services/SmtpEmailService.cs +++ b/Wave/Services/SmtpEmailService.cs @@ -1,4 +1,5 @@ -using MailKit.Net.Smtp; +using MailKit; +using MailKit.Net.Smtp; using MailKit.Security; using Microsoft.Extensions.Options; using MimeKit; @@ -43,7 +44,7 @@ public class SmtpEmailService(ILogger logger, IOptions logger, IOptions logger, IOptions TryReconnect(CancellationToken cancellation) { + int reconnectCount = 0; + while (true) { + try { + await DisconnectAsync(cancellation); + await ConnectAsync(cancellation); + return true; + } catch (Exception ex1) { + reconnectCount++; + // 2^11 = 2048 seconds ~= 34 minutes + if (reconnectCount <= 11) { + // 2 4 6 8 16 32 64... seconds + int waitTime = (int)Math.Pow(2, reconnectCount); + Logger.LogError(ex1, "Reconnect failed, Try: {ReconnectTry}. Will wait {ReconnectWaitTime} Seconds for next attempt.", reconnectCount, waitTime); + await Task.Delay(TimeSpan.FromSeconds(waitTime), cancellation); + } else { + Logger.LogCritical(ex1, "Reconnect retry count exceeded, giving up."); + return false; + } + } + } + } } \ No newline at end of file