< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Utilities.HostingExtensions
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Utilities/HostingExtensions.cs
Tag: Kestrun/Kestrun@9d3a582b2d63930269564a7591aa77ef297cadeb
Line coverage
0%
Covered lines: 0
Uncovered lines: 29
Coverable lines: 29
Total lines: 87
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 10
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
RunUntilShutdownAsync()0%110100%
Handler()100%210%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Utilities/HostingExtensions.cs

#LineLine coverage
 1using System.Text;
 2using Kestrun.Hosting;
 3using Serilog;
 4
 5namespace Kestrun.Utilities;
 6
 7/// <summary>
 8/// Provides extension methods for hosting Kestrun servers.
 9/// </summary>
 10public static class HostingExtensions
 11{
 12    /// <summary>
 13    /// Starts <paramref name="server"/>, blocks until the process receives
 14    /// Ctrl-C / SIGTERM (or <paramref name="stopToken"/> is cancelled),
 15    /// then calls <c>StopAsync</c> and disposes the host.
 16    /// </summary>
 17    /// <remarks>
 18    /// <para>Intended for console apps’ <c>Main</c>; keeps boiler-plate out
 19    /// of every sample you write.</para>
 20    /// <para>If <paramref name="configureConsole"/> is <see langword="true"/>
 21    /// (default) the method hooks <see cref="Console.CancelKeyPress"/>.
 22    /// In a service/daemon scenario you can pass <see langword="false"/>
 23    /// and supply your own cancellation token.</para>
 24    /// </remarks>
 25    public static async Task RunUntilShutdownAsync(
 26        this KestrunHost server,
 27        bool configureConsole = true,
 28        Encoding? consoleEncoding = null,
 29        Action? onStarted = null,
 30        Action<Exception>? onShutdownError = null,
 31        CancellationToken stopToken = default)
 32    {
 033        ArgumentNullException.ThrowIfNull(server);
 034        if (consoleEncoding != null)
 35        {
 036            Console.OutputEncoding = consoleEncoding;
 037            Console.InputEncoding = consoleEncoding;
 38        }
 039        using var linked = CancellationTokenSource.CreateLinkedTokenSource(stopToken);
 040        var done = new TaskCompletionSource<object?>(
 041                       TaskCreationOptions.RunContinuationsAsynchronously);
 42
 43        // ① optional Ctrl-C handler
 044        if (configureConsole)
 45        {
 046            Console.CancelKeyPress += Handler;
 47        }
 48
 49        // ② start + user callback
 050        await server.StartAsync(linked.Token);
 051        onStarted?.Invoke();
 052        Log.Information("Kestrun server started. Press Ctrl+C to stop.");
 53
 54        // ③ wait for either Ctrl-C or external cancellation
 055        using (stopToken.Register(() => done.TrySetResult(null)))
 56        {
 057            _ = await done.Task;
 058        }
 59
 60        // ④ graceful shutdown
 61        try
 62        {
 063            await server.StopAsync();
 064        }
 065        catch (Exception ex)
 66        {
 067            onShutdownError?.Invoke(ex);
 068            Log.Debug(ex, "Ignored exception during server shutdown.");
 069        }
 70        finally
 71        {
 072            server.Dispose();
 073            if (configureConsole)
 74            {
 075                Console.CancelKeyPress -= Handler;
 76            }
 77        }
 78
 79        // local function so we can unregister it
 80        void Handler(object? _, ConsoleCancelEventArgs e)
 81        {
 082            e.Cancel = true;          // prevent immediate process kill
 083            linked.Cancel();          // wake up the await
 084            _ = done.TrySetResult(null);
 085        }
 086    }
 87}

Methods/Properties

RunUntilShutdownAsync()
Handler()