fix(social): cap relay connect with a timeout so one hung relay can't stall the pool
This commit is contained in:
parent
3b84ecc7f4
commit
83ffc5cb1d
2 changed files with 50 additions and 4 deletions
|
|
@ -26,19 +26,32 @@ class RelayPool implements NostrChannel {
|
|||
/// Number of relays currently connected (for diagnostics/tests).
|
||||
int get relayCount => _connections.length;
|
||||
|
||||
/// Connects to each of [relayUrls], skipping any that fail. Throws
|
||||
/// [StateError] only when NONE are reachable, so the caller can treat that as
|
||||
/// "offline".
|
||||
/// Connects to each of [relayUrls], skipping any that fail or take longer
|
||||
/// than [connectTimeout] — a relay on a silently-filtering network would
|
||||
/// otherwise hang the whole pool for minutes. Throws [StateError] only when
|
||||
/// NONE are reachable, so the caller can treat that as "offline".
|
||||
static Future<RelayPool> connect(
|
||||
List<String> relayUrls, {
|
||||
required NostrIdentity identity,
|
||||
Duration connectTimeout = const Duration(seconds: 10),
|
||||
}) async {
|
||||
final connections = <NostrConnection>[];
|
||||
await Future.wait(
|
||||
relayUrls.map((url) async {
|
||||
try {
|
||||
final attempt = NostrConnection.connect(url, identity: identity);
|
||||
connections.add(
|
||||
await NostrConnection.connect(url, identity: identity),
|
||||
await attempt.timeout(
|
||||
connectTimeout,
|
||||
onTimeout: () {
|
||||
// Abandon the hung attempt; if it ever completes, close it so
|
||||
// the socket doesn't leak.
|
||||
unawaited(
|
||||
attempt.then((c) => c.close()).catchError((_) {}),
|
||||
);
|
||||
throw TimeoutException('relay connect timed out', connectTimeout);
|
||||
},
|
||||
),
|
||||
);
|
||||
} catch (_) {
|
||||
// Unreachable relay — skip it, keep the rest.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue