fetchFromServer method

Future<AppMetadata?> fetchFromServer(
  1. Client client,
  2. String serverId, {
  3. int retries = 0,
  4. Duration retryDelay = const Duration(milliseconds: 300),
})

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;
}