cosullivan / SmtpServer

A SMTP Server component written in C#
MIT License
690 stars 163 forks source link

Degradation: 9.0.2 doesn't gracefully shutdown #183

Closed xsharper closed 11 months ago

xsharper commented 1 year ago

Hello!

There is a small bug in 9.0.2 release. Can be reproduced by:

        static async Task Main()
        {
            var options = new SmtpServerOptionsBuilder()
                .ServerName("localhost")
                .Port(587)
                .Build();

            var serviceProvider = new ServiceProvider();
            var smtpServer = new SmtpServer.SmtpServer(options, serviceProvider);
            using (var cs = new CancellationTokenSource())
            {

                var smtpTask = smtpServer.StartAsync(cs.Token);
                var delay = Task.Delay(TimeSpan.FromSeconds(1));

                Console.WriteLine("Getting ready...");
                var cancelledTask=await Task.WhenAny(smtpTask, delay).ConfigureAwait(false);

                Debug.Assert(cancelledTask==delay);

                Console.WriteLine("Cancelled!");
                cs.Cancel();
                await smtpTask;

                Console.WriteLine("SMTP server is down. This never happens.");
                Console.ReadLine();
            }
        }

9.0.1 works fine.

P.S. Linked cancellation source behaves in counterintuitive way:

var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(1));
var linked = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token);
try
{
    await Task.Delay(TimeSpan.FromSeconds(5), timeout.Token);
}
catch (OperationCanceledException)
{
    ;
}

Console.WriteLine("Before using linked token");
Console.WriteLine($"Timeout: {timeout.Token.IsCancellationRequested}");
Console.WriteLine($"Linked: {linked.Token.IsCancellationRequested}");

try
{
    await Task.Delay(10000,linked.Token);
}
catch
{
    ;
}
Console.WriteLine("After using linked token");
Console.WriteLine($"Timeout: {timeout.Token.IsCancellationRequested}");
Console.WriteLine($"Linked: {linked.Token.IsCancellationRequested}");
nefarius commented 1 year ago

For those who can't wait for an official update feel free to use my fork in the meantime.