mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-09-14 21:45:25 +02:00
Fix late background alerts and cache starvation
- Increase background refresh threshold: Raised the edge distance check in GpsController from 1000m to 2500m to guarantee new Overpass data is fetched well before the user drives out of the cached bounding box. - Fix bounding box race condition: Added await to the background fetch handler in MapView so tracking bounds only shift forward after the network request successfully finishes. - Make debounced fetches awaitable: Refactored fetchAndUpdate in NodeProviderWithCache to return a Future<void> using a Completer, bridging the 400ms debounce timer. - Prevent hanging futures: Added state checks for _activeCompleter to instantly resolve canceled network requests during rapid map panning, preventing fatal StateError crashes and infinite UI hangs.
This commit is contained in:
@@ -333,9 +333,9 @@ class GpsController {
|
||||
final minDist = [northDist, southDist, eastDist, westDist].reduce((a, b) => a < b ? a : b);
|
||||
|
||||
// Debug 2: Print the closest distance to the edge
|
||||
debugPrint('[GpsController-Background] Closest edge distance: ${minDist.toStringAsFixed(1)}m (Threshold: 1000m)');
|
||||
debugPrint('[GpsController-Background] Closest edge distance: ${minDist.toStringAsFixed(1)}m (Threshold: 2500m)');
|
||||
|
||||
if (minDist < 1000) {
|
||||
if (minDist < 2500) {
|
||||
debugPrint('[GpsController-Background] Threshold crossed. Triggering refresh.');
|
||||
needsRefresh = true;
|
||||
}
|
||||
@@ -554,4 +554,4 @@ class GpsController {
|
||||
_onMapMovedProgrammatically = null;
|
||||
_isUserInteracting = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ class MapViewState extends State<MapView> with WidgetsBindingObserver {
|
||||
if (!mounted) return;
|
||||
final appState = context.read<AppState>();
|
||||
|
||||
NodeProviderWithCache.instance.fetchAndUpdate(
|
||||
await NodeProviderWithCache.instance.fetchAndUpdate(
|
||||
bounds: bounds,
|
||||
profiles: appState.enabledProfiles,
|
||||
uploadMode: appState.uploadMode,
|
||||
|
||||
@@ -17,6 +17,7 @@ class NodeProviderWithCache extends ChangeNotifier {
|
||||
|
||||
final NodeDataManager _nodeDataManager = NodeDataManager();
|
||||
Timer? _debounceTimer;
|
||||
Completer<void>? _activeCompleter;
|
||||
|
||||
/// Get cached nodes for the given bounds, filtered by enabled profiles
|
||||
List<OsmNode> getCachedNodesForBounds(LatLngBounds bounds) {
|
||||
@@ -34,14 +35,21 @@ class NodeProviderWithCache extends ChangeNotifier {
|
||||
}
|
||||
|
||||
/// Fetch and update nodes for the given view, with debouncing for rapid map movement
|
||||
void fetchAndUpdate({
|
||||
Future<void> fetchAndUpdate({
|
||||
required LatLngBounds bounds,
|
||||
required List<NodeProfile> profiles,
|
||||
UploadMode uploadMode = UploadMode.production,
|
||||
}) {
|
||||
// Serve cached immediately
|
||||
notifyListeners();
|
||||
|
||||
|
||||
// Prevent hanging awaits by completing the previous request if it gets cancelled
|
||||
if (_activeCompleter != null && !_activeCompleter!.isCompleted) {
|
||||
_activeCompleter!.complete();
|
||||
}
|
||||
|
||||
_activeCompleter = Completer<void>();
|
||||
|
||||
// Debounce rapid panning/zooming
|
||||
_debounceTimer?.cancel();
|
||||
_debounceTimer = Timer(const Duration(milliseconds: 400), () async {
|
||||
@@ -52,15 +60,21 @@ class NodeProviderWithCache extends ChangeNotifier {
|
||||
uploadMode: uploadMode,
|
||||
isUserInitiated: true,
|
||||
);
|
||||
|
||||
|
||||
// Notify UI of new data
|
||||
notifyListeners();
|
||||
|
||||
} catch (e) {
|
||||
debugPrint('[NodeProviderWithCache] Node fetch failed: $e');
|
||||
// Cache already holds whatever is available for the view
|
||||
} finally {
|
||||
// Ensure we only complete if it hasn't been superseded by another call
|
||||
if (_activeCompleter != null && !_activeCompleter!.isCompleted) {
|
||||
_activeCompleter!.complete();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return _activeCompleter!.future;
|
||||
}
|
||||
|
||||
/// Clear the cache and repopulate with pending nodes from upload queue
|
||||
@@ -108,4 +122,4 @@ class NodeProviderWithCache extends ChangeNotifier {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user