Detect config drift in cached tile providers and replace stale instances

When a user edits a tile type's URL template, max zoom, or API key
without changing IDs, the cached DeflockTileProvider would keep the old
frozen config. Now _getOrCreateProvider() computes a config fingerprint
and replaces the provider when drift is detected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Doug Borg
2026-03-04 10:12:49 -07:00
parent f3f40f36ef
commit 91e5177056
7 changed files with 197 additions and 13 deletions
@@ -359,8 +359,8 @@ void main() {
group('ProviderTileCacheStore eviction', () {
/// Helper: populate cache with [count] tiles, each [bytesPerTile] bytes.
/// Uses small delays between writes so modification times are
/// distinguishable for oldest-modified ordering.
/// Sets deterministic modification times (1 second apart) so eviction
/// ordering is stable across platforms without relying on wall-clock delays.
Future<void> fillCache(
ProviderTileCacheStore store, {
required int count,
@@ -373,14 +373,22 @@ void main() {
lastModified: null,
etag: null,
);
final baseTime = DateTime.utc(2026, 1, 1);
for (var i = 0; i < count; i++) {
await store.putTile(
url: 'https://tile.example.com/$prefix$i.png',
metadata: metadata,
bytes: bytes,
);
// Small delay so modification times are distinguishable for eviction order
await Future<void>.delayed(const Duration(milliseconds: 10));
// Set deterministic mtime so eviction order is stable across platforms.
final key = ProviderTileCacheStore.keyFor(
'https://tile.example.com/$prefix$i.png',
);
final tileFile = File(p.join(store.cacheDirectory, '$key.tile'));
final metaFile = File(p.join(store.cacheDirectory, '$key.meta'));
final mtime = baseTime.add(Duration(seconds: i));
await tileFile.setLastModified(mtime);
await metaFile.setLastModified(mtime);
}
}