flutter_network_watcher 0.0.4
flutter_network_watcher: ^0.0.4 copied to clipboard
Real-time network connectivity monitoring with offline queue management for Flutter applications.
Flutter Network Watcher #
A comprehensive Flutter package for monitoring network connectivity and managing offline requests with advanced retry logic and queue management.
Features #
- Network Connectivity Monitoring: Real-time monitoring of network status changes
- Offline Queue Management: Queue requests when offline and execute when back online
- Advanced Retry Logic: Sophisticated retry mechanisms with exponential backoff and jitter
- Dead Letter Queue: Handle failed requests that exceed retry limits
- Priority-based Processing: Execute requests based on priority and creation time
- Persistent Storage: Queue persistence across app sessions
- Configurable Retry Strategies: Customizable retry delays and conditions
- Comprehensive Analytics: Detailed statistics and monitoring capabilities
- Perfect Code Quality: Achieved full 160/160 Pana analysis score
- Multi-Platform Support: Supports all 6 Flutter platforms (iOS, Android, Web, Windows, macOS, Linux)
Getting Started #
Installation #
Add the dependency to your pubspec.yaml
:
dependencies:
flutter_network_watcher: ^0.0.4
Basic Usage #
import 'package:flutter_network_watcher/flutter_network_watcher.dart';
// Create a network watcher with default configuration
final networkWatcher = NetworkWatcher();
// Start monitoring
await networkWatcher.start();
// Queue a request for execution when online
final request = NetworkRequest(
id: 'unique_id',
method: 'POST',
url: 'https://api.example.com/data',
body: '{"key": "value"}',
priority: 5,
maxRetries: 3,
);
await networkWatcher.queueRequest(request);
// Listen to connectivity changes
networkWatcher.connectivityStream.listen((state) {
print('Connectivity: $state');
});
// Check if online
if (networkWatcher.isOnline) {
print('Device is online');
}
// Dispose when done
await networkWatcher.dispose();
Advanced Configuration #
Retry-Optimized Configuration #
// Configuration optimized for reliability with aggressive retries
final config = NetworkWatcherConfig.reliabilityOptimized.copyWith(
enableLogging: true,
retryDelayStrategy: NetworkWatcherConfig.exponentialBackoffWithJitter,
deadLetterQueueEnabled: true,
maxDeadLetterQueueSize: 100,
);
final networkWatcher = NetworkWatcher(config: config);
Custom Retry Strategies #
// Custom exponential backoff with jitter
Duration customRetryDelay(int retryCount) {
final baseDelay = Duration(seconds: (2 * retryCount).clamp(1, 60));
final jitter = Duration(milliseconds: (baseDelay.inMilliseconds * 0.1).round());
return Duration(milliseconds: baseDelay.inMilliseconds + jitter.inMilliseconds);
}
final config = NetworkWatcherConfig(
retryDelayStrategy: customRetryDelay,
maxRetryDelay: Duration(minutes: 10),
retryJitter: true,
);
Selective Retry Configuration #
final request = NetworkRequest(
id: 'selective_retry',
method: 'POST',
url: 'https://api.example.com/upload',
retryOnSpecificErrors: true,
retryableErrorTypes: ['timeout', 'server_error'],
maxRetries: 5,
);
Request Management #
Creating Requests #
final request = NetworkRequest(
id: 'unique_identifier',
method: 'POST',
url: 'https://api.example.com/endpoint',
headers: {'Content-Type': 'application/json'},
body: '{"data": "value"}',
priority: 10, // Higher number = higher priority
maxRetries: 3,
metadata: {'description': 'Important sync request'},
);
Priority and Ordering #
Requests are automatically ordered by:
- Priority (higher numbers first)
- Creation Time (older requests first for same priority)
// High priority request (executed first)
await networkWatcher.queueRequest(NetworkRequest(
id: 'critical_sync',
method: 'POST',
url: 'https://api.example.com/sync',
priority: 10,
));
// Low priority request (executed last)
await networkWatcher.queueRequest(NetworkRequest(
id: 'analytics',
method: 'POST',
url: 'https://analytics.example.com/event',
priority: 1,
));
Retry Logic #
Automatic Retry Conditions #
The package automatically retries requests based on:
- HTTP Status Codes: 408, 429, 500, 502, 503, 504 (configurable)
- Network Errors: Timeouts, connection failures, network unavailability
- Server Errors: 5xx status codes
- Client Errors: 4xx status codes (configurable)
Retry Delay Strategies #
Default Exponential Backoff
// Delay = 2 * retryCount seconds (capped at 60 seconds)
Duration delay = Duration(seconds: (2 * retryCount).clamp(1, 60));
Exponential Backoff with Jitter
// Adds 10% random jitter to prevent thundering herd
final config = NetworkWatcherConfig(
retryDelayStrategy: NetworkWatcherConfig.exponentialBackoffWithJitter,
retryJitter: true,
);
Custom Strategies
Duration customStrategy(int retryCount) {
return Duration(seconds: retryCount * 5); // Linear 5-second increments
}
final config = NetworkWatcherConfig(
retryDelayStrategy: customStrategy,
);
Dead Letter Queue #
When requests exceed their maximum retry attempts, they can be moved to a dead letter queue for analysis and manual retry.
Enabling Dead Letter Queue #
final config = NetworkWatcherConfig(
deadLetterQueueEnabled: true,
maxDeadLetterQueueSize: 100,
);
final networkWatcher = NetworkWatcher(config: config);
Accessing Dead Letter Queue #
final deadLetterQueue = networkWatcher.deadLetterQueue;
if (deadLetterQueue != null) {
// Get failed requests
final failedRequests = deadLetterQueue.getAllRequests();
// Get requests by failure reason
final timeoutRequests = deadLetterQueue.getRequestsByFailureReason('timeout');
// Get requests by status code
final serverErrorRequests = deadLetterQueue.getRequestsByStatusCode(500);
// Retry a specific request
await deadLetterQueue.retryRequest('request_id');
// Get statistics
final stats = deadLetterQueue.getStatistics();
}
Monitoring and Analytics #
Queue Statistics #
final stats = networkWatcher.getQueueStatistics();
print('Total Requests: ${stats['totalRequests']}');
print('Queue Utilization: ${stats['utilizationPercent']}%');
print('Priority Distribution: ${stats['priorityGroups']}');
print('Retry Distribution: ${stats['retryGroups']}');
print('Dead Letter Queue Size: ${stats['deadLetterQueueSize']}');
Individual Request Retry Stats #
final retryStats = networkWatcher.getRetryStats('request_id');
print('Retry Count: ${retryStats['retryCount']}/${retryStats['maxRetries']}');
print('Can Retry: ${retryStats['canRetry']}');
print('Last Retry Time: ${retryStats['lastRetryTime']}');
print('Next Retry Delay: ${retryStats['nextRetryDelay']}');
print('Failure Reason: ${retryStats['failureReason']}');
Requests Ready for Retry #
final readyRequests = networkWatcher.getRequestsReadyForRetry();
print('${readyRequests.length} requests ready for retry');
Configuration Options #
NetworkWatcherConfig #
Option | Default | Description |
---|---|---|
checkInterval |
5 seconds | How often to check connectivity when offline |
autoRetry |
true | Automatically retry failed requests when back online |
maxQueueSize |
100 | Maximum number of requests in the offline queue |
persistQueue |
true | Persist queue across app sessions |
maxRequestAge |
24 hours | Maximum age of requests before cleanup |
enableLogging |
false | Enable debug logging |
maxRetryDelay |
5 minutes | Maximum retry delay (prevents excessive delays) |
retryJitter |
true | Add jitter to retry delays |
deadLetterQueueEnabled |
false | Enable dead letter queue for failed requests |
maxDeadLetterQueueSize |
50 | Maximum size of dead letter queue |
retryableStatusCodes |
[408, 429, 500, 502, 503, 504] | HTTP status codes that trigger retries |
retryOnNetworkErrors |
true | Retry on network errors (timeouts, connection failures) |
retryOnServerErrors |
true | Retry on server errors (5xx status codes) |
retryOnClientErrors |
false | Retry on client errors (4xx status codes) |
Predefined Configurations #
Default Configuration
final config = NetworkWatcherConfig.defaultConfig;
Battery Optimized
final config = NetworkWatcherConfig.batteryOptimized;
// Longer check intervals, smaller queue, shorter max age
Real-time Responsive
final config = NetworkWatcherConfig.realTime;
// Frequent checks, larger queue, minimal delays
Reliability Optimized
final config = NetworkWatcherConfig.reliabilityOptimized;
// Aggressive retries, dead letter queue, longer delays
Error Handling #
Network Exceptions #
try {
await networkWatcher.queueRequest(request);
} on QueueFullException catch (e) {
print('Queue is full: ${e.maxSize}');
} on QueueException catch (e) {
print('Queue error: ${e.message}');
} on RequestExecutionException catch (e) {
print('Request failed: ${e.message} (Status: ${e.statusCode})');
}
Exception Types #
QueueFullException
: Offline queue has reached maximum capacityQueueException
: General queue operation failuresRequestExecutionException
: Network request execution failuresConnectivityException
: Network connectivity detection failuresPersistenceException
: Queue persistence operation failures
Platform Support #
- ✅ Android: Full support with native connectivity monitoring
- ✅ iOS: Full support with native connectivity monitoring
- ✅ Web: Basic support (limited connectivity detection)
- ✅ Windows: Full support with native connectivity monitoring
- ✅ macOS: Full support with native connectivity monitoring
- ✅ Linux: Full support with native connectivity monitoring
Example #
See the example/
directory for a complete working example demonstrating:
- Basic network monitoring
- Request queuing and retry logic
- Dead letter queue management
- Statistics and analytics
- Configuration options
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.