fix(social): cap relay connect with a timeout so one hung relay can't stall the pool

This commit is contained in:
vjrj 2026-07-22 12:48:55 +02:00
parent 3b84ecc7f4
commit 83ffc5cb1d
2 changed files with 50 additions and 4 deletions

View file

@ -1,3 +1,4 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:commons_core/commons_core.dart';
@ -58,6 +59,38 @@ void main() {
await r1.stop();
});
test('a hung relay cannot stall the pool past the connect timeout', () async {
// A server that accepts TCP but never answers the WebSocket handshake
// the shape of a silently-filtered network, where connect hangs for minutes.
final hang = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
final held = <Socket>[];
hang.listen(held.add);
final r1 = await MiniRelay.start();
final alice = await idFor(5);
final sw = Stopwatch()..start();
final pool = await RelayPool.connect(
[r1.url, 'ws://127.0.0.1:${hang.port}'],
identity: alice,
connectTimeout: const Duration(milliseconds: 500),
);
sw.stop();
expect(pool.relayCount, 1, reason: 'the live relay is kept');
expect(
sw.elapsed,
lessThan(const Duration(seconds: 5)),
reason: 'the hung relay must not stall the whole pool',
);
await pool.close();
for (final s in held) {
s.destroy();
}
await hang.close();
await r1.stop();
});
test('throws when no relay is reachable (caller treats as offline)', () async {
final alice = await idFor(4);
expect(