- Completed Action 2.5.1.3: Audited offlineQueue utility - Created OFFLINE_QUEUE_AUDIT.md with complete analysis - Verified core functionality: queue management, priority system, persistence, retry logic - Verified integration: Error interceptor queues network errors (line 999-1007) - Verified UI integration: OfflineIndicator displays queue size - Documented queue configuration: 100 request limit, 3 retries, 24h expiry - Identified potential issues: FormData serialization, token refresh on replay - Provided recommendations for testing and improvements
6.8 KiB
Offline Queue Utility Audit
Date: 2025-01-27
Action: 2.5.1.3 - Audit offlineQueue utility
Status: ✅ Complete
Overview
This document audits the offlineQueue utility to verify it works correctly and documents its usage.
File Location
- Source:
apps/web/src/services/offlineQueue.ts - Exports:
offlineQueue(singleton instance),QueuedRequest,QueueOptions - Purpose: Queue failed requests when offline and replay when connection is restored
Implementation Analysis
Core Functionality
The utility stores failed requests due to network issues and replays them when connection is restored.
Key Features:
- Offline Detection: Uses
navigator.onLineAPI - Request Queuing: Stores failed mutation requests (POST, PUT, DELETE, PATCH)
- Priority Support: High, normal, low priority levels
- Persistent Storage: Saves queue to localStorage
- Automatic Replay: Processes queue when connection restored
- Retry Logic: Maximum 3 retries with exponential backoff
Queue Configuration
Default Settings:
- Max Queue Size: 100 requests
- Default Max Retries: 3 attempts
- Default Retry Delay: 1 second (increases with retry count)
- Request Expiry: 24 hours (old requests filtered on load)
Request Filtering
Method: shouldQueueRequest(config: AxiosRequestConfig): boolean
Rules:
- ❌ GET requests: Not queued (can be retried fresh when online)
- ✅ Mutations: POST, PUT, DELETE, PATCH are queued
- Rationale: GET requests are idempotent and can be retried, mutations need to be preserved
Queue Management
Priority System:
- High priority: Processed first
- Normal priority: Processed after high
- Low priority: Processed last, first to be evicted if queue is full
Queue Eviction:
- If queue is full (100 requests):
- Try to remove oldest low-priority request
- If no low-priority, remove oldest request (FIFO)
Queue Persistence:
- Saved to
localStoragekey:veza_offline_queue - Loaded on service initialization
- Old requests (>24 hours) filtered out on load
Queue Processing
Method: processQueue(): Promise<void>
Processing Flow:
- Check if already processing or offline → Skip
- Process requests in priority order (high → normal → low)
- Retry each request via
apiClient.request() - On success → Remove from queue
- On failure → Increment retry count
- Max retries reached → Remove from queue (failed)
- Otherwise → Move to end of queue for retry
- Delay between requests (100ms) to avoid overwhelming server
- Exponential backoff on retries
Online Event Listener:
- Listens for
window.addEventListener('online') - Automatically processes queue when connection restored
Storage Format
localStorage Key: veza_offline_queue
Storage Format: JSON array of QueuedRequest objects
[
{
id: "req_1234567890_abc123",
config: { method: "POST", url: "/tracks", data: {...} },
timestamp: 1234567890000,
retryCount: 0,
priority: "normal"
}
]
Limitations:
- AxiosRequestConfig may contain non-serializable data (functions, File objects)
- File uploads may not serialize correctly to JSON
Integration Points
API Client Integration
Location: apps/web/src/services/api/client.ts:999-1007 (error interceptor)
Actual Implementation:
// FE-API-015: Queue request for offline replay if it's a network error
if (!error.response && originalRequest && offlineQueue.shouldQueueRequest(originalRequest)) {
const priority = originalRequest.method === 'POST' ? 'high' : 'normal';
try {
await offlineQueue.queueRequest(originalRequest, { priority });
} catch (queueError) {
logger.error('[API] Failed to queue request for offline replay', { error: queueError });
}
}
Behavior:
- ✅ Queues network errors (no response received)
- ✅ Only queues mutations (POST, PUT, DELETE, PATCH)
- ✅ Priority: POST = high, others = normal
- ✅ Error handling: Catches queue errors gracefully
Status: ✅ Verified - Fully integrated
Current Usage
Files using offlineQueue:
- ✅
apps/web/src/services/api/client.ts:999-1007- Error interceptor queues network errors - ✅
apps/web/src/components/OfflineIndicator.tsx- Shows queue size in UI - ✅
apps/web/src/services/api/client.ts:204-processQueue()function (may be related)
UI Integration:
OfflineIndicator.tsxdisplays queue size- Updates when queue size changes
Status: ✅ Utility is actively used and integrated
Verification
✅ Correct Behavior
- Offline Detection: Uses
navigator.onLineAPI - Request Filtering: Only queues mutations (correct)
- Priority System: High/normal/low priority support
- Persistence: Saves to localStorage, survives page reloads
- Automatic Replay: Processes queue on online event
- Retry Logic: Exponential backoff, max 3 retries
- Queue Limits: Maximum 100 requests, FIFO eviction
- Old Request Cleanup: Filters requests older than 24 hours
⚠️ Potential Issues
- Serialization: AxiosRequestConfig may contain non-serializable data (File objects, functions)
- File Uploads: FormData/file uploads may not serialize correctly to JSON
- ✅ Integration: Verified - Error interceptor queues network errors (line 999-1007)
- ✅ Error Filtering: Only queues network errors (
!error.response) - Correct behavior - Token Refresh: Queued requests may have expired tokens when replayed (needs verification)
🔧 Recommendations
- ✅ Integration: Verified - Error interceptor queues requests correctly
- File Upload Handling: Special handling for FormData/file uploads (may need to skip queueing or handle differently)
- Token Refresh: Verify tokens are refreshed before replaying queued requests
- ✅ Error Filtering: Already correct - Only queues network errors
- ✅ UI Feedback: Already implemented - OfflineIndicator shows queue size
- Testing: Test with actual offline scenarios, file uploads, token expiration
Testing Recommendations
- Unit Tests: Test queueing, priority, persistence, retry logic
- Integration Tests: Test with actual API calls, offline simulation
- Edge Cases: Test queue full, old requests, file uploads, token expiration
- Browser Testing: Test
navigator.onLinebehavior across browsers
Documentation Status
✅ Implementation documented
✅ Usage patterns identified
✅ Integration verified (error interceptor)
✅ UI integration verified (OfflineIndicator)
⏭️ Next: Action 2.5.1.4 - Add UI for offline queue management (may already be partially implemented)
Validation
✅ Utility implementation reviewed
✅ Functionality verified
✅ Integration points identified
✅ Potential issues documented
✅ Recommendations provided