#838

Npgsql 10.x ObjectDisposedException with Supavisor under high latency

Openfthsrlkopened 9mo ago

Description

When using Npgsql 10.x (.NET) with Supavisor (Transaction Pooler or Shared Pooler), ObjectDisposedException occurs on ManualResetEventSlim.Reset() under high latency conditions (500-1200ms).

Direct Connection (PgBouncer) works correctly with the exact same code.

Environment

  • Npgsql: 10.0.1
  • Npgsql.EntityFrameworkCore.PostgreSQL: 10.0.0
  • .NET: 10.0
  • EF Core: 10.0
  • Network latency: 500-1200ms (Istanbul to EU-Central-1)
  • Supabase region: EU-Central-1

Reproduction

Using EF Core's standard ExecutionStrategy pattern with transactions:

var strategy = context.Database.CreateExecutionStrategy();
await strategy.ExecuteAsync(async () =>
{
    await using var transaction = await context.Database.BeginTransactionAsync();
    // Single sequential operation
    await context.SaveChangesAsync();
    await transaction.CommitAsync();
});

Test Results

Connection TypeBackendResult
Transaction PoolerSupavisor❌ ObjectDisposedException
Session PoolerSupavisor❌ ObjectDisposedException
Direct ConnectionPgBouncer✅ Works correctly

Stack Trace

System.ObjectDisposedException: The event has been disposed.
   at System.Threading.ManualResetEventSlim.ThrowObjectDisposedException()
   at System.Threading.ManualResetEventSlim.Reset()
   at Npgsql.Internal.NpgsqlConnector.ResetCancellation()
   at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|212_0()
   ...

Workaround

Using Direct Connection instead of Transaction/Shared Pooler bypasses Supavisor and resolves the issue.

Related Issues

  • npgsql/npgsql#6415
  • npgsql/efcore.pg#3699

Multiple users have confirmed this behavior. The Npgsql team indicated this is likely related to how Supavisor handles connection lifecycle under high latency conditions.

Expected Behavior

Supavisor should handle Npgsql 10.x connections the same way PgBouncer (Direct Connection) does, without causing ObjectDisposedException.

Activity

1
SalomonHenke7mo ago

.