Skip to content

Commit b2d1def

Browse files
committed
fix(core-backend): improve traces
1 parent 01702fe commit b2d1def

File tree

6 files changed

+394
-274
lines changed

6 files changed

+394
-274
lines changed

packages/core-backend/CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- Improve WebSocket connection lifecycle tracing in `BackendWebSocketService` ([#7101](https://github.com/MetaMask/core/pull/7101))
13+
- WebSocket connection duration is now properly reflected in trace span duration instead of only in custom data
14+
- Trace all disconnections (both manual and unexpected) to provide complete connection lifecycle visibility in traces
15+
- Omit `connectionDuration_ms` from disconnection traces when connection never established (onClose without onOpen)
16+
- Update `BackendWebSocketService` default exponential backoff options for reconnection ([#7101](https://github.com/MetaMask/core/pull/7101))
17+
- Increase default `reconnectDelay` from 500 milliseconds to 10 seconds
18+
- Increase default `maxReconnectDelay` from 30 seconds to 60 seconds
19+
- Simplify WebSocket disconnection code in `BackendWebSocketService` ([#7101](https://github.com/MetaMask/core/pull/7101))
20+
- Centralize all disconnection logic in `ws.onclose` handler for single source of truth
21+
- Centralize all state changes within `#establishConnection` method - state transitions only occur in `onopen` (CONNECTING → CONNECTED) and `onclose` (any state → DISCONNECTED)
22+
- Add `MANUAL_DISCONNECT_CODE` (4999) and `MANUAL_DISCONNECT_REASON` constants to distinguish manual from unexpected disconnects
23+
24+
### Removed
25+
26+
- Remove `BackendWebSocketService Channel Message` trace as it provided no useful performance insights ([#7101](https://github.com/MetaMask/core/pull/7101))
27+
1028
## [4.0.0]
1129

1230
### Changed

packages/core-backend/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ sequenceDiagram
311311
#### Key Flow Characteristics
312312

313313
1. **Initial Setup**: BackendWebSocketService establishes connection, then AccountActivityService subscribes to selected account. Backend automatically sends a system notification with all chains that are currently up. AccountActivityService tracks these chains internally and notifies TokenBalancesController, which increases polling interval to 5 min
314-
2. **Chain Status Tracking**: AccountActivityService maintains an internal set of chains that are 'up' based on system notifications. On disconnect/error, it marks all tracked chains as 'down' before clearing the set
314+
2. **Chain Status Tracking**: AccountActivityService maintains an internal set of chains that are 'up' based on system notifications. On disconnect, it marks all tracked chains as 'down' before clearing the set
315315
3. **System Notifications**: Backend automatically sends chain status updates (up/down) upon subscription and when status changes. AccountActivityService forwards these to TokenBalancesController, which adjusts polling intervals (up: 5min, down: 30s + immediate fetch)
316316
4. **User Account Changes**: When users switch accounts, AccountActivityService unsubscribes from old account and subscribes to new account. Backend sends fresh system notification with current chain status for the new account
317317
5. **Connection Resilience**: On reconnection, AccountActivityService resubscribes to selected account and receives fresh chain status via system notification. Automatic reconnection with exponential backoff

packages/core-backend/src/AccountActivityService.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -686,11 +686,11 @@ describe('AccountActivityService', () => {
686686
timestamp: 1760344704595,
687687
});
688688

689-
// Publish WebSocket ERROR state event - should flush tracked chains as down
689+
// Publish WebSocket DISCONNECTED state event - should flush tracked chains as down
690690
rootMessenger.publish(
691691
'BackendWebSocketService:connectionStateChanged',
692692
{
693-
state: WebSocketState.ERROR,
693+
state: WebSocketState.DISCONNECTED,
694694
url: 'ws://test',
695695
reconnectAttempts: 2,
696696
timeout: 10000,
@@ -701,7 +701,7 @@ describe('AccountActivityService', () => {
701701
);
702702
await completeAsyncOperations(100);
703703

704-
// Verify that the ERROR state triggered the status change for tracked chains
704+
// Verify that the DISCONNECTED state triggered the status change for tracked chains
705705
expect(statusChangedEventListener).toHaveBeenCalledWith({
706706
chainIds: ['eip155:1', 'eip155:137', 'eip155:56'],
707707
status: 'down',
@@ -720,11 +720,11 @@ describe('AccountActivityService', () => {
720720

721721
mocks.getSelectedAccount.mockReturnValue(null);
722722

723-
// Publish WebSocket ERROR state event without any tracked chains
723+
// Publish WebSocket DISCONNECTED state event without any tracked chains
724724
rootMessenger.publish(
725725
'BackendWebSocketService:connectionStateChanged',
726726
{
727-
state: WebSocketState.ERROR,
727+
state: WebSocketState.DISCONNECTED,
728728
url: 'ws://test',
729729
reconnectAttempts: 2,
730730
timeout: 10000,

packages/core-backend/src/AccountActivityService.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,15 @@ export class AccountActivityService {
451451
status: data.status,
452452
timestamp,
453453
});
454+
455+
log(
456+
`WebSocket status change - Published tracked chains as ${data.status}`,
457+
{
458+
count: data.chainIds.length,
459+
chains: data.chainIds,
460+
status: data.status,
461+
},
462+
);
454463
}
455464

456465
/**
@@ -467,11 +476,8 @@ export class AccountActivityService {
467476
// WebSocket connected - resubscribe to selected account
468477
// The system notification will automatically provide the list of chains that are up
469478
await this.#subscribeToSelectedAccount();
470-
} else if (
471-
state === WebSocketState.DISCONNECTED ||
472-
state === WebSocketState.ERROR
473-
) {
474-
// On disconnect/error, flush all tracked chains as down
479+
} else if (state === WebSocketState.DISCONNECTED) {
480+
// On disconnect, flush all tracked chains as down
475481
const chainsToMarkDown = Array.from(this.#chainsUp);
476482

477483
if (chainsToMarkDown.length > 0) {
@@ -481,13 +487,10 @@ export class AccountActivityService {
481487
timestamp: Date.now(),
482488
});
483489

484-
log(
485-
'WebSocket error/disconnection - Published tracked chains as down',
486-
{
487-
count: chainsToMarkDown.length,
488-
chains: chainsToMarkDown,
489-
},
490-
);
490+
log('WebSocket disconnection - Published tracked chains as down', {
491+
count: chainsToMarkDown.length,
492+
chains: chainsToMarkDown,
493+
});
491494

492495
// Clear the tracking set since all chains are now down
493496
this.#chainsUp.clear();

0 commit comments

Comments
 (0)