NEON-15: dispose shared NpgsqlDataSource on host shutdown

pull/32/head
VinPropane 2026-04-08 21:42:33 -04:00
parent abffd29299
commit 90fcd1b717
3 changed files with 19 additions and 2 deletions

View File

@ -21,7 +21,8 @@ public sealed class InMemoryWebApplicationFactory : WebApplicationFactory<Progra
if (d.ServiceType == typeof(IPositionStateStore) ||
d.ServiceType == typeof(NpgsqlDataSource) ||
(d.ServiceType == typeof(IHostedService) &&
d.ImplementationType == typeof(PostgresDevPlayerSeedHostedService)))
(d.ImplementationType == typeof(PostgresDevPlayerSeedHostedService) ||
d.ImplementationType == typeof(NpgsqlDataSourceShutdownHostedService))))
{
services.RemoveAt(i);
}

View File

@ -0,0 +1,15 @@
using Microsoft.Extensions.Hosting;
using Npgsql;
namespace NeonSprawl.Server.Game.PositionState;
/// <summary>Disposes the shared <see cref="NpgsqlDataSource"/> when the host stops. Registered before <see cref="PostgresDevPlayerSeedHostedService"/> so <see cref="IHostedService.StopAsync"/> runs last (NEON-15).</summary>
internal sealed class NpgsqlDataSourceShutdownHostedService(NpgsqlDataSource dataSource) : IHostedService
{
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public async Task StopAsync(CancellationToken cancellationToken)
{
await dataSource.DisposeAsync();
}
}

View File

@ -13,7 +13,8 @@ public static class PositionStateServiceCollectionExtensions
if (!string.IsNullOrWhiteSpace(cs))
{
var trimmed = cs.Trim();
services.AddSingleton(_ => Npgsql.NpgsqlDataSource.Create(trimmed));
services.AddSingleton<Npgsql.NpgsqlDataSource>(_ => Npgsql.NpgsqlDataSource.Create(trimmed));
services.AddHostedService<NpgsqlDataSourceShutdownHostedService>();
services.AddHostedService<PostgresDevPlayerSeedHostedService>();
services.AddSingleton<IPositionStateStore, PostgresPositionStateStore>();
}