fetchFromServer method
FR-META-001, 002 — best-effort Online fetch.
The ui://app/info read fires right after the connection handshake, so
the first attempt can race a cold remote server or a not-yet-warm
streamable-HTTP response channel and come back empty/erroring. When the
caller knows the resource actually exists (it was in listResources),
pass retries > 0 so a transient miss is retried with a short backoff
instead of silently yielding null — the launcher tile would otherwise
keep its fallback name until the user re-enters the app enough times to
hit a lucky timing. A genuine miss (resource absent, malformed payload)
still returns null on the first pass without burning retries.
Implementation
Future<AppMetadata?> fetchFromServer(
Client client,
String serverId, {
int retries = 0,
Duration retryDelay = const Duration(milliseconds: 300),
}) async {
for (var attempt = 0; attempt <= retries; attempt++) {
final (metadata, transient) = await _tryFetch(client, serverId, attempt);
if (metadata != null) return metadata;
// Only a transient failure (empty/error) is worth retrying; a
// definitive miss (payload present but not an object) is not.
if (!transient || attempt == retries) return null;
await Future<void>.delayed(retryDelay);
}
return null;
}