|
| 1 | +# SignalR Service and Map Hook Refactoring |
| 2 | + |
| 3 | +## Summary of Changes |
| 4 | + |
| 5 | +This refactoring addresses multiple issues with the SignalR service and map updates to prevent concurrent API calls, improve performance, and ensure thread safety. |
| 6 | + |
| 7 | +## Key Issues Addressed |
| 8 | + |
| 9 | +1. **Multiple concurrent calls to GetMapDataAndMarkers**: SignalR events were triggering multiple simultaneous API calls |
| 10 | +2. **Lack of singleton enforcement**: SignalR service singleton pattern wasn't thread-safe |
| 11 | +3. **No request cancellation**: In-flight requests weren't being cancelled when new events came in |
| 12 | +4. **No debouncing**: Rapid consecutive SignalR events caused unnecessary API calls |
| 13 | +5. **No connection locking**: Multiple concurrent connection attempts to the same hub were possible |
| 14 | + |
| 15 | +## Changes Made |
| 16 | + |
| 17 | +### 1. Enhanced SignalR Service (`src/services/signalr.service.ts`) |
| 18 | + |
| 19 | +#### Thread-Safe Singleton Pattern |
| 20 | +- Added proper singleton instance management with race condition protection |
| 21 | +- Added `resetInstance()` method for testing purposes |
| 22 | +- Improved singleton creation with polling mechanism to prevent multiple instances |
| 23 | + |
| 24 | +#### Connection Locking |
| 25 | +- Added `connectionLocks` Map to prevent concurrent connections to the same hub |
| 26 | +- Added locking for `connectToHubWithEventingUrl()` and `connectToHub()` methods |
| 27 | +- Added waiting logic for `disconnectFromHub()` and `invoke()` methods to wait for ongoing connections |
| 28 | + |
| 29 | +#### Improved Reconnection Logic |
| 30 | +- Enhanced `handleConnectionClose()` with better error handling and logging |
| 31 | +- Added proper cleanup on max reconnection attempts reached |
| 32 | +- Improved connection state management during reconnection attempts |
| 33 | +- Added check to prevent reconnection if connection was re-established during delay |
| 34 | + |
| 35 | +#### Better Error Handling |
| 36 | +- Enhanced logging for all connection states |
| 37 | +- Improved error context in log messages |
| 38 | +- Added proper cleanup on connection failures |
| 39 | + |
| 40 | +### 2. Refactored Map Hook (`src/hooks/use-map-signalr-updates.ts`) |
| 41 | + |
| 42 | +#### Debouncing |
| 43 | +- Added 1-second debounce delay to prevent rapid consecutive API calls |
| 44 | +- Uses `setTimeout` to debounce SignalR update events |
| 45 | + |
| 46 | +#### Concurrency Prevention |
| 47 | +- Added `isUpdating` ref to prevent multiple concurrent API calls |
| 48 | +- Only one `getMapDataAndMarkers` call can be active at a time |
| 49 | + |
| 50 | +#### Request Cancellation |
| 51 | +- Added `AbortController` support to cancel in-flight requests |
| 52 | +- Previous requests are automatically cancelled when new updates come in |
| 53 | +- Proper cleanup of abort controllers |
| 54 | + |
| 55 | +#### Enhanced Error Handling |
| 56 | +- Added special handling for `AbortError` (logged as debug, not error) |
| 57 | +- Improved error context in log messages |
| 58 | +- Better error recovery mechanisms |
| 59 | + |
| 60 | +#### Proper Cleanup |
| 61 | +- Added cleanup for debounce timers on unmount |
| 62 | +- Added cleanup for abort controllers on unmount |
| 63 | +- Proper cleanup in useEffect dependency arrays |
| 64 | + |
| 65 | +## Performance Improvements |
| 66 | + |
| 67 | +1. **Reduced API Calls**: Debouncing prevents excessive API calls during rapid SignalR events |
| 68 | +2. **Request Cancellation**: Prevents unnecessary processing of outdated requests |
| 69 | +3. **Singleton Enforcement**: Ensures only one SignalR service instance exists |
| 70 | +4. **Connection Reuse**: Prevents duplicate connections to the same hub |
| 71 | +5. **Better Memory Management**: Proper cleanup prevents memory leaks |
| 72 | + |
| 73 | +## Testing |
| 74 | + |
| 75 | +### New Test Coverage |
| 76 | +- Comprehensive test suite for `useMapSignalRUpdates` hook (14 tests) |
| 77 | +- Tests for debouncing, concurrency prevention, error handling, and cleanup |
| 78 | +- Tests for AbortController integration |
| 79 | +- Tests for edge cases and error scenarios |
| 80 | + |
| 81 | +### Enhanced SignalR Service Tests |
| 82 | +- Added tests for singleton behavior |
| 83 | +- Added tests for connection locking |
| 84 | +- Enhanced existing test coverage |
| 85 | +- Added tests for improved reconnection logic |
| 86 | + |
| 87 | +## Configuration |
| 88 | + |
| 89 | +### Debounce Timing |
| 90 | +- Default debounce delay: 1000ms (configurable via `DEBOUNCE_DELAY` constant) |
| 91 | +- Can be adjusted based on performance requirements |
| 92 | + |
| 93 | +### Reconnection Settings |
| 94 | +- Max reconnection attempts: 5 (unchanged) |
| 95 | +- Reconnection interval: 5000ms (unchanged) |
| 96 | +- Enhanced with better cleanup and state management |
| 97 | + |
| 98 | +## Backward Compatibility |
| 99 | + |
| 100 | +All changes are backward compatible: |
| 101 | +- Public API of SignalR service remains unchanged |
| 102 | +- Map hook interface remains the same |
| 103 | +- Existing functionality is preserved with performance improvements |
| 104 | + |
| 105 | +## Usage |
| 106 | + |
| 107 | +The refactored components work transparently with existing code: |
| 108 | + |
| 109 | +```typescript |
| 110 | +// SignalR service usage remains the same |
| 111 | +const signalRService = SignalRService.getInstance(); |
| 112 | +await signalRService.connectToHubWithEventingUrl(config); |
| 113 | + |
| 114 | +// Map hook usage remains the same |
| 115 | +useMapSignalRUpdates(onMarkersUpdate); |
| 116 | +``` |
| 117 | + |
| 118 | +## Benefits |
| 119 | + |
| 120 | +1. **Improved Performance**: Fewer unnecessary API calls, better request management |
| 121 | +2. **Better User Experience**: Faster map updates, reduced server load |
| 122 | +3. **Enhanced Reliability**: Better error handling, improved connection management |
| 123 | +4. **Memory Efficiency**: Proper cleanup prevents memory leaks |
| 124 | +5. **Thread Safety**: Singleton pattern prevents race conditions |
| 125 | +6. **Testability**: Comprehensive test coverage ensures reliability |
| 126 | + |
| 127 | +## Future Considerations |
| 128 | + |
| 129 | +1. **Configurable Debounce**: Could make debounce delay configurable via environment variables |
| 130 | +2. **Request Priority**: Could implement priority system for different types of updates |
| 131 | +3. **Caching**: Could add intelligent caching for map data |
| 132 | +4. **Health Monitoring**: Could add connection health monitoring and reporting |
0 commit comments