WalReceiverTimeout = Timeout.InfiniteTimeSpan causes immediate TimeoutException during StartReplication in Npgsql 10
Description
Setting WalReceiverTimeout = Timeout.InfiniteTimeSpan on a LogicalReplicationConnection causes an immediate TimeoutException during StartReplication in Npgsql 10.0.1. The same code worked correctly in Npgsql 9.0.4.
This appears to be a consequence of the Npgsql 10 breaking change where Timeout.InfiniteTimeSpan is now correctly interpreted as infinite (previously it was misinterpreted as TimeSpan.Zero). However, passing an infinite wal_receiver_timeout to Postgres during the START_REPLICATION handshake causes Postgres to immediately close the connection, which Npgsql surfaces as a TimeoutException.
Repro
const string connectionString = "Host=localhost;Port=5432;Database=YOUR_DB;Username=YOUR_USER;Password=YOUR_PASSWORD";
const string publicationName = "YOUR_PUBLICATION"; // Must already exist
const string slotName = "test_repro_slot";
try
{
await using var conn = new LogicalReplicationConnection(connectionString);
conn.WalReceiverTimeout = Timeout.InfiniteTimeSpan; // <---- this line causes the issue
await conn.Open();
var slot = await conn.CreatePgOutputReplicationSlot(slotName, true);
await foreach (var message in conn.StartReplication(slot,
new PgOutputReplicationOptions(publicationName, PgOutputProtocolVersion.V2),
CancellationToken.None))
{
Console.WriteLine($"Received message type: {message.GetType().Name}");
conn.SetReplicationStatus(message.WalEnd);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.Read();
Expected behavior
The replication stream connects and waits indefinitely for messages, consistent with Timeout.InfiniteTimeSpan semantics.
Actual behavior
Npgsql.NpgsqlException: Exception while reading from stream
---> System.TimeoutException: Timeout during reading attempt
at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(...)
at Npgsql.Replication.ReplicationConnection.StartReplicationInternal(...)
Workaround
Use TimeSpan.Zero instead of Timeout.InfiniteTimeSpan.
Environment
|
|
| Npgsql |
10.0.1 |
| PostgreSQL |
14.19 |
| .NET |
10 |
WalReceiverTimeout = Timeout.InfiniteTimeSpancauses immediateTimeoutExceptionduringStartReplicationin Npgsql 10Description
Setting
WalReceiverTimeout = Timeout.InfiniteTimeSpanon aLogicalReplicationConnectioncauses an immediateTimeoutExceptionduringStartReplicationin Npgsql 10.0.1. The same code worked correctly in Npgsql 9.0.4.This appears to be a consequence of the Npgsql 10 breaking change where
Timeout.InfiniteTimeSpanis now correctly interpreted as infinite (previously it was misinterpreted asTimeSpan.Zero). However, passing an infinitewal_receiver_timeoutto Postgres during theSTART_REPLICATIONhandshake causes Postgres to immediately close the connection, which Npgsql surfaces as aTimeoutException.Repro
Expected behavior
The replication stream connects and waits indefinitely for messages, consistent with
Timeout.InfiniteTimeSpansemantics.Actual behavior
Workaround
Use
TimeSpan.Zeroinstead ofTimeout.InfiniteTimeSpan.Environment