diff --git a/.editorconfig b/.editorconfig deleted file mode 120000 index 3ca15af8..00000000 --- a/.editorconfig +++ /dev/null @@ -1 +0,0 @@ -Settings/.editorconfig \ No newline at end of file diff --git a/csharp/Platform.Data.Doublets.Gql.Server/GracefulShutdownService.cs b/csharp/Platform.Data.Doublets.Gql.Server/GracefulShutdownService.cs new file mode 100644 index 00000000..ab52a203 --- /dev/null +++ b/csharp/Platform.Data.Doublets.Gql.Server/GracefulShutdownService.cs @@ -0,0 +1,41 @@ +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Platform.Data.Doublets.Gql.Server +{ + public class GracefulShutdownService : IHostedService + { + private readonly IHostApplicationLifetime _applicationLifetime; + private readonly ILogger _logger; + + public GracefulShutdownService(IHostApplicationLifetime applicationLifetime, ILogger logger) + { + _applicationLifetime = applicationLifetime; + _logger = logger; + } + + public Task StartAsync(CancellationToken cancellationToken) + { + _applicationLifetime.ApplicationStopping.Register(OnApplicationStopping); + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + + private void OnApplicationStopping() + { + _logger.LogInformation("Application is stopping. Initiating graceful shutdown for WebSocket connections..."); + + // Give some time for active connections to close gracefully + Thread.Sleep(TimeSpan.FromSeconds(2)); + + _logger.LogInformation("Graceful shutdown completed."); + } + } +} \ No newline at end of file diff --git a/csharp/Platform.Data.Doublets.Gql.Server/Program.cs b/csharp/Platform.Data.Doublets.Gql.Server/Program.cs index 65f962cb..6850419d 100644 --- a/csharp/Platform.Data.Doublets.Gql.Server/Program.cs +++ b/csharp/Platform.Data.Doublets.Gql.Server/Program.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.DependencyInjection; using Platform.IO; using Serilog; using Serilog.Events; @@ -35,6 +36,13 @@ public static int Main(params string[] args) } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) + .ConfigureServices((context, services) => + { + services.Configure(options => + { + options.ShutdownTimeout = TimeSpan.FromSeconds(30); + }); + }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseSerilog().UseStartup(); diff --git a/csharp/Platform.Data.Doublets.Gql.Server/StartupWithRouting.cs b/csharp/Platform.Data.Doublets.Gql.Server/StartupWithRouting.cs index 1f02a833..1d34cc4f 100644 --- a/csharp/Platform.Data.Doublets.Gql.Server/StartupWithRouting.cs +++ b/csharp/Platform.Data.Doublets.Gql.Server/StartupWithRouting.cs @@ -39,6 +39,7 @@ public void ConfigureServices(IServiceCollection services) => services.AddRoutin }) .AddSingleton(sp => Data.CreateLinks()) .AddSingleton() + .AddHostedService() .AddGraphQL((options, provider) => { options.EnableMetrics = Environment.IsDevelopment();