closeIdleConnections method
Closes connections that no longer carry any tracked network work.
Call this after optional subscriptions stop, for example when an app goes into the background. This is not an eviction timer: a live subscription keeps its connection even after EOSE, and authentication/reconnect work keeps the exact connection it is preparing to use.
Request discovery does not yet identify every target connection. Defer pruning while such work is in progress instead of guessing its targets. Broadcasts track relay URLs rather than identities, so both anonymous and authenticated connections at an in-flight broadcast's URL are retained.
Implementation
Future<void> closeIdleConnections() async {
var changed = false;
try {
for (final key in globalState.relays.keys.toList()) {
// Re-evaluate after each asynchronous close. Another operation may
// have claimed the next connection while the previous one was closing.
if (_hasUnassignedConnectionWork()) break;
if (_connectionHasWork(key)) continue;
await closeConnection(key);
changed = true;
}
} finally {
if (changed) updateRelayConnectivity();
}
}