implemented a 1-minute in-memory cache for the EmergencyNoticeClient to prevent redundant network requests on app resume

This commit is contained in:
2026-07-16 10:47:51 +02:00
parent 7c1f5c06df
commit e349d667d4
3 changed files with 43 additions and 56 deletions
+28 -11
View File
@@ -2,17 +2,30 @@ import 'package:dio/dio.dart';
import 'emergency_notice.dart';
/// Loads the emergency notice from a foreign URL over a standalone [Dio]
/// instance — no MarianumConnect interceptors, base URL or auth. That keeps the
/// fallback fully independent of the backend it is meant to survive.
/// Loads the emergency notice from a foreign URL over a standalone [Dio] — no
/// MarianumConnect interceptors/base URL/auth, so it survives a backend outage.
/// Never throws: any failure yields `null` (nothing shown).
///
/// Fail-safe by contract: if the server is unreachable, times out, answers with
/// a non-2xx status or delivers unparsable content, [fetch] returns `null` and
/// nothing is shown. It never throws.
/// A [cacheTtl] in-memory throttle keeps rapid resumes from hammering the host;
/// it lives only for the process, so a cold start always fetches fresh.
class EmergencyNoticeClient {
const EmergencyNoticeClient();
EmergencyNoticeClient();
static const Duration cacheTtl = Duration(minutes: 1);
EmergencyNotice? _cached;
String? _cachedUrl;
DateTime? _cachedAt;
Future<EmergencyNotice?> fetch(String url) async {
final cachedAt = _cachedAt;
if (cachedAt != null &&
_cachedUrl == url &&
DateTime.now().difference(cachedAt) < cacheTtl) {
return _cached;
}
EmergencyNotice? result;
try {
final dio = Dio(
BaseOptions(
@@ -24,11 +37,15 @@ class EmergencyNoticeClient {
);
final response = await dio.get<String>(url);
final raw = response.data;
if (raw == null || raw.isEmpty) return null;
return EmergencyNotice.parse(raw);
result = (raw == null || raw.isEmpty) ? null : EmergencyNotice.parse(raw);
} catch (_) {
// Server down / timeout / bad status / malformed body: show nothing.
return null;
result = null;
}
// Cache failures too, so a down server isn't retried on every resume.
_cached = result;
_cachedUrl = url;
_cachedAt = DateTime.now();
return result;
}
}