-
Notifications
You must be signed in to change notification settings - Fork 4
CU-868fdadum Expo update for And16k, bug fixes and tweaks. #166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
700fee1
48cdfbe
a8b83f5
388856e
5fd3e37
83c0704
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| # SignalR Service Reconnection Self-Blocking Fix | ||
|
|
||
| ## Problem | ||
|
|
||
| The SignalR service had a self-blocking issue where reconnection attempts would prevent direct connection attempts. Specifically: | ||
|
|
||
| 1. When a hub was in "reconnecting" state, direct connection attempts would be blocked | ||
| 2. This could lead to scenarios where: | ||
| - A reconnection attempt was in progress | ||
| - A user tried to manually connect | ||
| - The manual connection would be rejected | ||
| - If the reconnection failed, the hub would be stuck in reconnecting state | ||
| - Future manual connection attempts would continue to be blocked | ||
|
|
||
| ## Root Cause | ||
|
|
||
| The service used a single `reconnectingHubs` Set to track both: | ||
| - Automatic reconnection attempts | ||
| - Direct connection attempts | ||
|
|
||
| This caused the guard logic in `_connectToHubInternal` (lines 240-246) to block direct connections when hubs were in reconnecting state. | ||
|
|
||
| ## Solution | ||
|
|
||
| Implemented a more granular state management system: | ||
|
|
||
| ### 1. New State Enum | ||
|
|
||
| ```typescript | ||
| export enum HubConnectingState { | ||
| IDLE = 'idle', | ||
| RECONNECTING = 'reconnecting', | ||
| DIRECT_CONNECTING = 'direct-connecting', | ||
| } | ||
| ``` | ||
|
|
||
| ### 2. State Management | ||
|
|
||
| - Added `hubStates: Map<string, HubConnectingState>` to track individual hub states | ||
| - Added `setHubState()` method to manage state transitions and maintain backward compatibility | ||
| - Added helper methods: `isHubConnecting()`, `isHubReconnecting()` | ||
|
|
||
| ### 3. Updated Connection Logic | ||
|
|
||
| **Direct Connections (`_connectToHubInternal` and `_connectToHubWithEventingUrlInternal`):** | ||
| - Only block duplicate direct connections (same `DIRECT_CONNECTING` state) | ||
| - Allow direct connections even when hub is in `RECONNECTING` state | ||
| - Log reconnecting state but proceed with connection attempt | ||
| - Set state to `DIRECT_CONNECTING` during connection attempt | ||
| - Clean up state on both success and failure | ||
|
|
||
| **Automatic Reconnections:** | ||
| - Set state to `RECONNECTING` during reconnection attempts | ||
| - Clean up state on both success and failure | ||
| - Maintain existing reconnection logic and limits | ||
|
|
||
| ### 4. Backward Compatibility | ||
|
|
||
| - Maintained the `reconnectingHubs` Set for existing API compatibility | ||
| - `setHubState()` automatically manages the legacy set alongside the new state map | ||
| - All existing methods continue to work as expected | ||
|
|
||
| ## Key Changes | ||
|
|
||
| 1. **Lines 240-246**: Changed from blocking all connections during reconnect to only blocking duplicate direct connections | ||
| 2. **State Management**: Added proper state tracking with cleanup in success/failure paths | ||
| 3. **Connection Isolation**: Reconnection attempts and direct connections now operate independently | ||
| 4. **Cleanup**: Ensured state cleanup happens in all code paths to prevent stuck states | ||
|
|
||
| ## Testing | ||
|
|
||
| - Updated existing tests to use new state management system | ||
| - All existing tests continue to pass | ||
| - Tests verify that direct connections are allowed during reconnection | ||
| - Tests verify proper state cleanup in success and failure scenarios | ||
|
|
||
| ## Benefits | ||
|
|
||
| - Eliminates self-blocking behavior during reconnections | ||
| - Allows users to manually retry connections even during automatic reconnection | ||
| - Prevents permanent stuck states | ||
| - Maintains full backward compatibility | ||
| - Provides better separation of concerns between automatic and manual connections |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| # SignalR Service and Map Hook Refactoring | ||
|
|
||
| ## Summary of Changes | ||
|
|
||
| This refactoring addresses multiple issues with the SignalR service and map updates to prevent concurrent API calls, improve performance, and ensure thread safety. | ||
|
|
||
| ## Key Issues Addressed | ||
|
|
||
| 1. **Multiple concurrent calls to GetMapDataAndMarkers**: SignalR events were triggering multiple simultaneous API calls | ||
| 2. **Lack of singleton enforcement**: SignalR service singleton pattern wasn't thread-safe | ||
| 3. **No request cancellation**: In-flight requests weren't being cancelled when new events came in | ||
| 4. **No debouncing**: Rapid consecutive SignalR events caused unnecessary API calls | ||
| 5. **No connection locking**: Multiple concurrent connection attempts to the same hub were possible | ||
|
|
||
| ## Changes Made | ||
|
|
||
| ### 1. Enhanced SignalR Service (`src/services/signalr.service.ts`) | ||
|
|
||
| #### Thread-Safe Singleton Pattern | ||
| - Added proper singleton instance management with race condition protection | ||
| - Added `resetInstance()` method for testing purposes | ||
| - Improved singleton creation with polling mechanism to prevent multiple instances | ||
|
|
||
| #### Connection Locking | ||
| - Added `connectionLocks` Map to prevent concurrent connections to the same hub | ||
| - Added locking for `connectToHubWithEventingUrl()` and `connectToHub()` methods | ||
| - Added waiting logic for `disconnectFromHub()` and `invoke()` methods to wait for ongoing connections | ||
|
|
||
| #### Improved Reconnection Logic | ||
| - Enhanced `handleConnectionClose()` with better error handling and logging | ||
| - Added proper cleanup on max reconnection attempts reached | ||
| - Improved connection state management during reconnection attempts | ||
| - Added check to prevent reconnection if connection was re-established during delay | ||
|
|
||
| #### Better Error Handling | ||
| - Enhanced logging for all connection states | ||
| - Improved error context in log messages | ||
| - Added proper cleanup on connection failures | ||
|
|
||
| ### 2. Refactored Map Hook (`src/hooks/use-map-signalr-updates.ts`) | ||
|
|
||
| #### Debouncing | ||
| - Added 1-second debounce delay to prevent rapid consecutive API calls | ||
| - Uses `setTimeout` to debounce SignalR update events | ||
|
|
||
| #### Concurrency Prevention | ||
| - Added `isUpdating` ref to prevent multiple concurrent API calls | ||
| - Only one `getMapDataAndMarkers` call can be active at a time | ||
|
|
||
| #### Request Cancellation | ||
| - Added `AbortController` support to cancel in-flight requests | ||
| - Previous requests are automatically cancelled when new updates come in | ||
| - Proper cleanup of abort controllers | ||
|
|
||
| #### Enhanced Error Handling | ||
| - Added special handling for `AbortError` (logged as debug, not error) | ||
| - Improved error context in log messages | ||
| - Better error recovery mechanisms | ||
|
|
||
| #### Proper Cleanup | ||
| - Added cleanup for debounce timers on unmount | ||
| - Added cleanup for abort controllers on unmount | ||
| - Proper cleanup in useEffect dependency arrays | ||
|
|
||
| ## Performance Improvements | ||
|
|
||
| 1. **Reduced API Calls**: Debouncing prevents excessive API calls during rapid SignalR events | ||
| 2. **Request Cancellation**: Prevents unnecessary processing of outdated requests | ||
| 3. **Singleton Enforcement**: Ensures only one SignalR service instance exists | ||
| 4. **Connection Reuse**: Prevents duplicate connections to the same hub | ||
| 5. **Better Memory Management**: Proper cleanup prevents memory leaks | ||
|
|
||
| ## Testing | ||
|
|
||
| ### New Test Coverage | ||
| - Comprehensive test suite for `useMapSignalRUpdates` hook (14 tests) | ||
| - Tests for debouncing, concurrency prevention, error handling, and cleanup | ||
| - Tests for AbortController integration | ||
| - Tests for edge cases and error scenarios | ||
|
|
||
| ### Enhanced SignalR Service Tests | ||
| - Added tests for singleton behavior | ||
| - Added tests for connection locking | ||
| - Enhanced existing test coverage | ||
| - Added tests for improved reconnection logic | ||
|
|
||
|
Comment on lines
+73
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify referenced tests and exports exist (avoid stale docs). Docs mention the hook tests and 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Checking hook file and export..."
fd use-map-signalr-updates.ts src | sed -n '1p' | xargs -I{} rg -n "export const DEBOUNCE_DELAY" {}
echo "Checking hook tests..."
fd -e ts -e tsx "__tests__" src/hooks | xargs -I{} rg -n "describe\\(.*useMapSignalRUpdates" {} -n -C1 || true
echo "Checking enhanced service tests..."
fd -e ts "signalr.service.enhanced.test.ts" src/services/__tests__ -x echo {}Length of output: 198 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
echo "1. Locate hook file containing useMapSignalRUpdates:"
rg -l "function useMapSignalRUpdates" -t ts || true
echo "2. Verify DEBOUNCE_DELAY export in source:"
rg -n "export const DEBOUNCE_DELAY" -t ts || true
echo "3. List all hook test files:"
find src/hooks -type f \( -name "*.test.ts" -o -name "*.spec.ts" -o -name "*.test.tsx" -o -name "*.spec.tsx" \) -print || true
echo "4. Search hook tests for useMapSignalRUpdates:"
rg -n "useMapSignalRUpdates" -C1 --glob "src/hooks/**/*.{test,spec}.{ts,tsx}" || true
echo "5. List all service test files:"
find src/services -type f \( -name "*.test.ts" -o -name "*.spec.ts" \) -print || true
echo "6. Search service tests for SignalR keywords (singleton, reconnect, connection):"
rg -nE "singleton|reconnect|connection" --glob "src/services/**/*.{test,spec}.ts" || trueLength of output: 6618 Remove stale
🧰 Tools🪛 LanguageTool[grammar] ~75-~75: There might be a mistake here. (QB_NEW_EN) [grammar] ~76-~76: There might be a mistake here. (QB_NEW_EN) [grammar] ~77-~77: There might be a mistake here. (QB_NEW_EN) [grammar] ~78-~78: There might be a mistake here. (QB_NEW_EN) [grammar] ~81-~81: There might be a mistake here. (QB_NEW_EN) 🤖 Prompt for AI Agents |
||
| ## Configuration | ||
|
|
||
| ### Debounce Timing | ||
| - Default debounce delay: 1000ms (configurable via `DEBOUNCE_DELAY` constant) | ||
| - Can be adjusted based on performance requirements | ||
|
|
||
| ### Reconnection Settings | ||
| - Max reconnection attempts: 5 (unchanged) | ||
| - Reconnection interval: 5000ms (unchanged) | ||
| - Enhanced with better cleanup and state management | ||
|
|
||
| ## Backward Compatibility | ||
|
|
||
| All changes are backward compatible: | ||
| - Public API of SignalR service remains unchanged | ||
| - Map hook interface remains the same | ||
| - Existing functionality is preserved with performance improvements | ||
|
|
||
| ## Usage | ||
|
|
||
| The refactored components work transparently with existing code: | ||
|
|
||
| ```typescript | ||
| // SignalR service usage remains the same | ||
| const signalRService = SignalRService.getInstance(); | ||
| await signalRService.connectToHubWithEventingUrl(config); | ||
|
|
||
| // Map hook usage remains the same | ||
| useMapSignalRUpdates(onMarkersUpdate); | ||
| ``` | ||
|
|
||
| ## Benefits | ||
|
|
||
| 1. **Improved Performance**: Fewer unnecessary API calls, better request management | ||
| 2. **Better User Experience**: Faster map updates, reduced server load | ||
| 3. **Enhanced Reliability**: Better error handling, improved connection management | ||
| 4. **Memory Efficiency**: Proper cleanup prevents memory leaks | ||
| 5. **Thread Safety**: Singleton pattern prevents race conditions | ||
| 6. **Testability**: Comprehensive test coverage ensures reliability | ||
|
|
||
| ## Future Considerations | ||
|
|
||
| 1. **Configurable Debounce**: Could make debounce delay configurable via environment variables | ||
| 2. **Request Priority**: Could implement priority system for different types of updates | ||
| 3. **Caching**: Could add intelligent caching for map data | ||
| 4. **Health Monitoring**: Could add connection health monitoring and reporting | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Align docs with the singleton implementation (remove “polling” language).
Code should not use a blocking polling loop for singleton creation. Update this section to describe simple lazy initialization.
🧰 Tools
🪛 LanguageTool
[grammar] ~19-~19: There might be a mistake here.
Context: ...ts`) #### Thread-Safe Singleton Pattern - Added proper singleton instance manageme...
(QB_NEW_EN)
🤖 Prompt for AI Agents