perf: performance improvements 1
This commit is contained in:
+6
@@ -340,6 +340,12 @@ export class PeerConnectionManager {
|
||||
return false;
|
||||
|
||||
try {
|
||||
// Release the failed channel before adopting the replacement; otherwise
|
||||
// its SCTP resources and handlers stay alive for the connection lifetime.
|
||||
try {
|
||||
expectedChannel.close();
|
||||
} catch { /* channel may already be closed */ }
|
||||
|
||||
const replacement = peerData.connection.createDataChannel(DATA_CHANNEL_LABEL, { ordered: true });
|
||||
|
||||
peerData.dataChannel = replacement;
|
||||
|
||||
+44
-1
@@ -5,7 +5,11 @@ import {
|
||||
PeerConnectionManagerContext,
|
||||
RecoveryHandlers
|
||||
} from '../shared';
|
||||
import { scheduleDataChannelRecovery } from './peer-recovery';
|
||||
import {
|
||||
closeAllPeers,
|
||||
removePeer,
|
||||
scheduleDataChannelRecovery
|
||||
} from './peer-recovery';
|
||||
|
||||
describe('peer recovery', () => {
|
||||
afterEach(() => {
|
||||
@@ -13,6 +17,40 @@ describe('peer recovery', () => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('removes every remote stream map entry for a removed peer, including camera streams', () => {
|
||||
const channel = createDataChannel(DATA_CHANNEL_STATE_OPEN);
|
||||
const context = createContext('alice');
|
||||
|
||||
context.state.activePeerConnections.set('bob', createPeerData(channel, 'connected'));
|
||||
context.state.remotePeerStreams.set('bob', createMediaStream());
|
||||
context.state.remotePeerVoiceStreams.set('bob', createMediaStream());
|
||||
context.state.remotePeerScreenShareStreams.set('bob', createMediaStream());
|
||||
context.state.remotePeerCameraStreams.set('bob', createMediaStream());
|
||||
|
||||
removePeer(context, 'bob');
|
||||
|
||||
expect(context.state.remotePeerStreams.has('bob')).toBe(false);
|
||||
expect(context.state.remotePeerVoiceStreams.has('bob')).toBe(false);
|
||||
expect(context.state.remotePeerScreenShareStreams.has('bob')).toBe(false);
|
||||
expect(context.state.remotePeerCameraStreams.has('bob')).toBe(false);
|
||||
});
|
||||
|
||||
it('clears every remote stream map when all peers close, including camera streams', () => {
|
||||
const context = createContext('alice');
|
||||
|
||||
context.state.remotePeerStreams.set('bob', createMediaStream());
|
||||
context.state.remotePeerVoiceStreams.set('bob', createMediaStream());
|
||||
context.state.remotePeerScreenShareStreams.set('bob', createMediaStream());
|
||||
context.state.remotePeerCameraStreams.set('bob', createMediaStream());
|
||||
|
||||
closeAllPeers(context.state);
|
||||
|
||||
expect(context.state.remotePeerStreams.size).toBe(0);
|
||||
expect(context.state.remotePeerVoiceStreams.size).toBe(0);
|
||||
expect(context.state.remotePeerScreenShareStreams.size).toBe(0);
|
||||
expect(context.state.remotePeerCameraStreams.size).toBe(0);
|
||||
});
|
||||
|
||||
it('recreates a peer immediately when the data channel is already closed', () => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
@@ -205,9 +243,14 @@ function createPeerData(
|
||||
};
|
||||
}
|
||||
|
||||
function createMediaStream(): MediaStream {
|
||||
return { getTracks: () => [] } as unknown as MediaStream;
|
||||
}
|
||||
|
||||
function createDataChannel(readyState: RTCDataChannelState): RTCDataChannel {
|
||||
return {
|
||||
bufferedAmount: 0,
|
||||
close: vi.fn(),
|
||||
label: 'chat',
|
||||
readyState
|
||||
} as unknown as RTCDataChannel;
|
||||
|
||||
+4
@@ -14,6 +14,7 @@ import {
|
||||
RemovePeerOptions
|
||||
} from '../shared';
|
||||
import { clearAllPingTimers, stopPingInterval } from '../messaging/ping';
|
||||
import { clearDebugNetworkPeerMetrics } from '../../logging/debug-network-metrics';
|
||||
|
||||
/**
|
||||
* Close and remove a peer connection, data channel, and emit a disconnect event.
|
||||
@@ -33,11 +34,13 @@ export function removePeer(
|
||||
if (!preserveReconnectState) {
|
||||
clearPeerReconnectTimer(state, peerId);
|
||||
state.disconnectedPeerTracker.delete(peerId);
|
||||
clearDebugNetworkPeerMetrics(peerId);
|
||||
}
|
||||
|
||||
state.remotePeerStreams.delete(peerId);
|
||||
state.remotePeerVoiceStreams.delete(peerId);
|
||||
state.remotePeerScreenShareStreams.delete(peerId);
|
||||
state.remotePeerCameraStreams.delete(peerId);
|
||||
|
||||
if (peerData) {
|
||||
if (peerData.dataChannel)
|
||||
@@ -72,6 +75,7 @@ export function closeAllPeers(state: PeerConnectionManagerState): void {
|
||||
state.remotePeerStreams.clear();
|
||||
state.remotePeerVoiceStreams.clear();
|
||||
state.remotePeerScreenShareStreams.clear();
|
||||
state.remotePeerCameraStreams.clear();
|
||||
state.peerNegotiationQueue.clear();
|
||||
state.peerLatencies.clear();
|
||||
state.pendingPings.clear();
|
||||
|
||||
Reference in New Issue
Block a user