@livedigital/client 3.25.2 → 3.25.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine/{ChannelStateSynchronizer.d.ts → ChannelStateSynchronyzer/ChannelStateSynchronizer.d.ts} +4 -6
- package/dist/engine/ChannelStateSynchronyzer/types.d.ts +17 -0
- package/dist/engine/DefaultEngineDependenciesFactory.d.ts +1 -1
- package/dist/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyCheckResult.d.ts +1 -9
- package/dist/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyChecker.d.ts +0 -7
- package/dist/engine/handlers/ChannelStateSyncEventHandler/index.d.ts +2 -2
- package/dist/engine/handlers/ChannelStateSyncEventHandler/types.d.ts +10 -3
- package/dist/errors/LivedigitalSDKError.d.ts +2 -1
- package/dist/errors/RequestError.d.ts +5 -0
- package/dist/index.es.js +3 -3
- package/dist/index.js +4 -4
- package/dist/types/engine.d.ts +3 -1
- package/package.json +1 -1
- package/src/engine/{ChannelStateSynchronizer.ts → ChannelStateSynchronyzer/ChannelStateSynchronizer.ts} +118 -70
- package/src/engine/ChannelStateSynchronyzer/types.ts +22 -0
- package/src/engine/DefaultEngineDependenciesFactory.ts +3 -1
- package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyCheckResult.ts +1 -12
- package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyChecker.ts +3 -40
- package/src/engine/handlers/ChannelStateSyncEventHandler/index.ts +60 -45
- package/src/engine/handlers/ChannelStateSyncEventHandler/types.ts +9 -4
- package/src/engine/index.ts +2 -1
- package/src/engine/media/tracks/PeerTrack.ts +2 -11
- package/src/engine/network/Socket.ts +2 -1
- package/src/engine/network/index.ts +34 -11
- package/src/errors/LivedigitalSDKError.ts +4 -1
- package/src/errors/RequestError.ts +9 -0
- package/src/types/engine.ts +5 -1
package/dist/types/engine.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { ActivityConfirmationRequiredPayload, AvailableMediaDevices, ChannelEven
|
|
|
11
11
|
import ChannelAudioObserverEventHandler from '../engine/handlers/ChannelAudioObserverEventHandler';
|
|
12
12
|
import { BaseTrack, MediaTracksFactory, Track, InitEffectsSDKParams } from './media';
|
|
13
13
|
import ChannelStateSyncEventHandler from '../engine/handlers/ChannelStateSyncEventHandler';
|
|
14
|
-
import ChannelStateSynchronizer, { ChannelStateSynchronizerParams } from '../engine/ChannelStateSynchronizer';
|
|
14
|
+
import ChannelStateSynchronizer, { ChannelStateSynchronizerParams } from '../engine/ChannelStateSynchronyzer/ChannelStateSynchronizer';
|
|
15
15
|
import { CLIENT_EVENTS, INTERNAL_CLIENT_EVENTS } from '../constants/events';
|
|
16
16
|
import Peer from '../engine/Peer';
|
|
17
17
|
import { InconsistenceType } from '../engine/handlers/ChannelStateSyncEventHandler/types';
|
|
@@ -68,6 +68,7 @@ export interface ChannelStateSyncEventHandlerParams {
|
|
|
68
68
|
webRTCIssueEmitter?: WebRTCIssueEmitter;
|
|
69
69
|
onLogMessage?: LogMessageHandler;
|
|
70
70
|
sendAnalytics: boolean;
|
|
71
|
+
channelStateSynchronizer: ChannelStateSynchronizer;
|
|
71
72
|
}
|
|
72
73
|
export interface ConnectParams {
|
|
73
74
|
channelId: string;
|
|
@@ -83,6 +84,7 @@ export interface ChannelStateInconsistentPayload {
|
|
|
83
84
|
type: InconsistenceType;
|
|
84
85
|
peerId?: string;
|
|
85
86
|
producerId?: string;
|
|
87
|
+
consumerId?: string;
|
|
86
88
|
}
|
|
87
89
|
export interface ProducePermissionsChangedPayload {
|
|
88
90
|
labels: TrackLabel[];
|
package/package.json
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { serializeError } from 'serialize-error';
|
|
2
|
-
import Logger from '
|
|
2
|
+
import Logger from '../Logger';
|
|
3
3
|
import {
|
|
4
4
|
LogLevel, LogMessageHandler, PeerResponse, PeerShortData,
|
|
5
|
-
} from '
|
|
5
|
+
} from '../../types/common';
|
|
6
6
|
import {
|
|
7
7
|
CHANNEL_EVENTS, CLIENT_EVENTS, MEDIASOUP_EVENTS, PEER_EVENTS,
|
|
8
|
-
} from '
|
|
9
|
-
import Peer from '
|
|
10
|
-
import { debounce, deepEqualObject } from '
|
|
11
|
-
import Engine from '
|
|
12
|
-
import {
|
|
8
|
+
} from '../../constants/events';
|
|
9
|
+
import Peer from '../Peer';
|
|
10
|
+
import { debounce, deepEqualObject } from '../../helpers/common';
|
|
11
|
+
import Engine from '../index';
|
|
12
|
+
import {
|
|
13
|
+
RestoreChannelStateResult,
|
|
14
|
+
RestoredLocalPeersStateResult,
|
|
15
|
+
RestoredProducersStateResult,
|
|
16
|
+
RestoredTracksResult,
|
|
17
|
+
} from './types';
|
|
13
18
|
|
|
14
19
|
const RESTORE_STATE_DEBOUNCE_TIME_MS = 3000;
|
|
15
|
-
const SYNC_CONSUMERS_DEBOUNCE_TIME_MS = 1000;
|
|
16
20
|
|
|
17
21
|
export interface ChannelStateSynchronizerParams {
|
|
18
22
|
engine: Engine;
|
|
@@ -28,8 +32,6 @@ class ChannelStateSynchronizer {
|
|
|
28
32
|
|
|
29
33
|
readonly debouncedRestoreState: <U>(this: U, ...args: Parameters<() => Promise<void>>) => void | Promise<void>;
|
|
30
34
|
|
|
31
|
-
readonly debouncedSyncPeerState: <U>(this: U, type: InconsistenceType) => void | Promise<void>;
|
|
32
|
-
|
|
33
35
|
constructor({
|
|
34
36
|
engine, onLogMessage, logLevel, sendAnalytics,
|
|
35
37
|
}: ChannelStateSynchronizerParams) {
|
|
@@ -42,86 +44,80 @@ class ChannelStateSynchronizer {
|
|
|
42
44
|
});
|
|
43
45
|
this.watchNetworkState();
|
|
44
46
|
this.debouncedRestoreState = debounce(this.restoreState.bind(this), RESTORE_STATE_DEBOUNCE_TIME_MS);
|
|
45
|
-
this.debouncedSyncPeerState = debounce(this.syncPeerState.bind(this), SYNC_CONSUMERS_DEBOUNCE_TIME_MS);
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
private watchNetworkState(): void {
|
|
49
50
|
this.#engine.clientEventEmitter.on(CLIENT_EVENTS.connectionRestored, async () => {
|
|
50
51
|
await this.debouncedRestoreState();
|
|
51
52
|
});
|
|
52
|
-
|
|
53
|
-
this.#engine.clientEventEmitter.on(CLIENT_EVENTS.channelStateInconsistent, async ({ type }) => {
|
|
54
|
-
if ([InconsistenceType.IncorrectConsumerState, InconsistenceType.MissingConsumers].includes(type)) {
|
|
55
|
-
await this.debouncedSyncPeerState(type);
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
53
|
}
|
|
59
54
|
|
|
60
|
-
|
|
55
|
+
async restoreState(): Promise<RestoreChannelStateResult> {
|
|
56
|
+
const result: RestoreChannelStateResult = {
|
|
57
|
+
missingPeers: [],
|
|
58
|
+
removedPeers: [],
|
|
59
|
+
missingProducers: [],
|
|
60
|
+
removedProducers: [],
|
|
61
|
+
fixedProducersState: [],
|
|
62
|
+
fixedConsumersState: [],
|
|
63
|
+
restoredAppDataPeers: [],
|
|
64
|
+
};
|
|
65
|
+
|
|
61
66
|
try {
|
|
62
67
|
if (!this.#engine.isSocketConnectionActive) {
|
|
63
|
-
this.#logger.info('Connection inactive, skipping
|
|
64
|
-
|
|
65
|
-
type,
|
|
66
|
-
});
|
|
67
|
-
return;
|
|
68
|
+
this.#logger.info('Connection inactive, skipping restore local state', { case: 'restoreLocalState' });
|
|
69
|
+
return result;
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
this.#engine.eventsQueue.pause();
|
|
71
73
|
|
|
72
|
-
this.#logger.info('
|
|
73
|
-
case: 'restoreLocalState',
|
|
74
|
-
type,
|
|
75
|
-
});
|
|
74
|
+
this.#logger.info('Restoring local state', { case: 'restoreLocalState' });
|
|
76
75
|
|
|
76
|
+
const localPeers = this.#engine.hostPeers.map((peer) => peer.shortData);
|
|
77
77
|
const { peers: clusterPeers } = await this.#engine.network.getChannelPeers('host');
|
|
78
|
-
|
|
78
|
+
|
|
79
|
+
const { removedProducers, fixedProducersState } = await this.restoreRemoteProducersState(clusterPeers);
|
|
80
|
+
result.removedProducers.push(...fixedProducersState);
|
|
81
|
+
result.removedProducers.push(...removedProducers);
|
|
82
|
+
|
|
83
|
+
result.removedPeers.push(...this.removeUnnecessaryPeers(localPeers, clusterPeers));
|
|
84
|
+
result.missingPeers.push(...this.setMissingPeers(localPeers, clusterPeers));
|
|
85
|
+
|
|
86
|
+
const restoreLocalStateResult = this.restoreLocalPeersState(clusterPeers);
|
|
87
|
+
result.missingProducers.push(...restoreLocalStateResult.missingProducers);
|
|
88
|
+
result.removedProducers.push(...restoreLocalStateResult.removedProducers);
|
|
89
|
+
result.restoredAppDataPeers.push(...restoreLocalStateResult.restoredAppDataPeers);
|
|
90
|
+
result.fixedProducersState.push(...restoreLocalStateResult.fixedProducersState);
|
|
91
|
+
result.fixedConsumersState.push(...restoreLocalStateResult.fixedConsumersState);
|
|
92
|
+
|
|
93
|
+
return result;
|
|
79
94
|
} catch (error) {
|
|
80
|
-
this.#logger.info('Failed to
|
|
95
|
+
this.#logger.info('Failed to restore local state', {
|
|
81
96
|
case: 'restoreLocalState',
|
|
82
|
-
type,
|
|
83
97
|
error: serializeError(error),
|
|
84
98
|
});
|
|
99
|
+
|
|
100
|
+
return result;
|
|
85
101
|
} finally {
|
|
86
102
|
this.#logger.info('Resume events after re-syncing local peers', {
|
|
87
103
|
case: 'restoreLocalState',
|
|
88
|
-
type,
|
|
89
104
|
accumulatedEventsAmount: this.#engine.eventsQueue.size(),
|
|
90
105
|
});
|
|
91
106
|
this.#engine.eventsQueue.resume();
|
|
92
107
|
}
|
|
93
108
|
}
|
|
94
109
|
|
|
95
|
-
private async
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
110
|
+
private async restoreRemoteProducersState(clusterPeers: PeerResponse[]): Promise<RestoredProducersStateResult> {
|
|
111
|
+
const results: RestoredProducersStateResult = {
|
|
112
|
+
removedProducers: [],
|
|
113
|
+
fixedProducersState: [],
|
|
114
|
+
};
|
|
101
115
|
|
|
102
|
-
this.#logger.info('Restoring local state', { case: 'restoreLocalState' });
|
|
103
|
-
|
|
104
|
-
const localPeers = this.#engine.hostPeers.map((peer) => peer.shortData);
|
|
105
|
-
const { peers: clusterPeers } = await this.#engine.network.getChannelPeers('host');
|
|
106
|
-
|
|
107
|
-
await this.restoreRemoteProducersState(clusterPeers);
|
|
108
|
-
this.removeUnnecessaryPeers(localPeers, clusterPeers);
|
|
109
|
-
this.setMissingPeers(localPeers, clusterPeers);
|
|
110
|
-
this.restoreLocalPeersState(clusterPeers);
|
|
111
|
-
} catch (error) {
|
|
112
|
-
this.#logger.info('Failed to restore local state', {
|
|
113
|
-
case: 'restoreLocalState',
|
|
114
|
-
error: serializeError(error),
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private async restoreRemoteProducersState(clusterPeers: PeerResponse[]): Promise<void> {
|
|
120
116
|
const myLocalPeer = this.#engine.peers.find((peer) => peer.id === this.#engine.myPeerId);
|
|
121
117
|
const myClusterPeer = clusterPeers.find((peer) => peer.id === this.#engine.myPeerId);
|
|
122
118
|
|
|
123
119
|
if (!myLocalPeer || !myClusterPeer) {
|
|
124
|
-
return;
|
|
120
|
+
return results;
|
|
125
121
|
}
|
|
126
122
|
|
|
127
123
|
// removing extra producers from server
|
|
@@ -132,6 +128,7 @@ class ChannelStateSynchronizer {
|
|
|
132
128
|
await Promise.all(unnecessaryLocalProducers.map(async (producer) => {
|
|
133
129
|
await this.#engine.network.closeRemoteProducer(producer.id);
|
|
134
130
|
myLocalPeer.producers.delete(producer.id);
|
|
131
|
+
results.removedProducers.push(producer.id);
|
|
135
132
|
this.#logger.info('Unnecessary local producer closed', {
|
|
136
133
|
case: 'restoreLocalState',
|
|
137
134
|
removedProducerId: producer.id,
|
|
@@ -144,47 +141,66 @@ class ChannelStateSynchronizer {
|
|
|
144
141
|
.filter((cp) => !!localTracks.find((track) => track.isPaused && (track.isPaused !== cp.paused)));
|
|
145
142
|
await Promise.all(wrongStateProducers.map(async (producer) => {
|
|
146
143
|
await this.#engine.network.pauseRemoteProducer(producer.id);
|
|
144
|
+
results.fixedProducersState.push(producer.id);
|
|
147
145
|
this.#logger.info('Remote producer state repaired', {
|
|
148
146
|
case: 'restoreLocalState',
|
|
149
147
|
removedProducerId: producer.id,
|
|
150
148
|
removedProducerPeerId: producer.peerId,
|
|
151
149
|
});
|
|
152
150
|
}));
|
|
151
|
+
|
|
152
|
+
return results;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
private removeUnnecessaryPeers(localPeers: PeerShortData[], clusterPeers: PeerResponse[]):
|
|
155
|
+
private removeUnnecessaryPeers(localPeers: PeerShortData[], clusterPeers: PeerResponse[]): string[] {
|
|
156
|
+
const results: string[] = [];
|
|
156
157
|
const unnecessaryPeers = localPeers
|
|
157
158
|
.filter((localPeer) => !clusterPeers.find((remotePeer) => remotePeer.id === localPeer.id));
|
|
158
159
|
|
|
159
160
|
unnecessaryPeers.forEach((unnecessaryPeer) => {
|
|
160
161
|
this.#engine.removePeer(unnecessaryPeer.id);
|
|
162
|
+
results.push(unnecessaryPeer.id);
|
|
161
163
|
this.#logger.info('Unnecessary peer removed', {
|
|
162
164
|
case: 'restoreLocalState',
|
|
163
165
|
removedPeerId: unnecessaryPeer.id,
|
|
164
166
|
});
|
|
165
167
|
});
|
|
168
|
+
|
|
169
|
+
return results;
|
|
166
170
|
}
|
|
167
171
|
|
|
168
|
-
private setMissingPeers(localPeers: PeerShortData[], clusterPeers: PeerResponse[]):
|
|
172
|
+
private setMissingPeers(localPeers: PeerShortData[], clusterPeers: PeerResponse[]): string[] {
|
|
173
|
+
const results: string[] = [];
|
|
169
174
|
clusterPeers.forEach((clusterPeer) => {
|
|
170
175
|
const peer = localPeers.find((localPeer) => localPeer.id === clusterPeer.id);
|
|
171
176
|
if (peer) {
|
|
172
177
|
return;
|
|
173
178
|
}
|
|
174
179
|
|
|
175
|
-
this.#engine.setPeer(clusterPeer);
|
|
180
|
+
const newPeer = this.#engine.setPeer(clusterPeer);
|
|
181
|
+
results.push(newPeer.id);
|
|
176
182
|
this.#logger.info('Missing peer added to storage', {
|
|
177
183
|
case: 'restoreLocalState',
|
|
178
184
|
peerId: clusterPeer.id,
|
|
179
185
|
});
|
|
180
186
|
});
|
|
187
|
+
|
|
188
|
+
return results;
|
|
181
189
|
}
|
|
182
190
|
|
|
183
|
-
private restoreLocalPeersState(clusterPeers: PeerResponse[]):
|
|
191
|
+
private restoreLocalPeersState(clusterPeers: PeerResponse[]): RestoredLocalPeersStateResult {
|
|
184
192
|
const clusterPeersMap = new Map(clusterPeers.map((peer) => [peer.id, peer]));
|
|
185
|
-
const
|
|
193
|
+
const localPeers = this.#engine.hostPeers;
|
|
194
|
+
|
|
195
|
+
const result: RestoredLocalPeersStateResult = {
|
|
196
|
+
removedProducers: [],
|
|
197
|
+
missingProducers: [],
|
|
198
|
+
restoredAppDataPeers: [],
|
|
199
|
+
fixedConsumersState: [],
|
|
200
|
+
fixedProducersState: [],
|
|
201
|
+
};
|
|
186
202
|
|
|
187
|
-
|
|
203
|
+
localPeers.forEach((localPeer) => {
|
|
188
204
|
const clusterPeer = clusterPeersMap.get(localPeer.id);
|
|
189
205
|
if (!clusterPeer) {
|
|
190
206
|
this.#logger.warn('Found new local peer, skip restoring state', {
|
|
@@ -195,32 +211,58 @@ class ChannelStateSynchronizer {
|
|
|
195
211
|
return;
|
|
196
212
|
}
|
|
197
213
|
|
|
198
|
-
this.removeUnnecessaryProducers(localPeer, clusterPeer);
|
|
199
|
-
|
|
200
|
-
this.
|
|
214
|
+
result.removedProducers.push(...this.removeUnnecessaryProducers(localPeer, clusterPeer));
|
|
215
|
+
|
|
216
|
+
const isAppDataRestored = this.restoreAppData(localPeer, clusterPeer);
|
|
217
|
+
if (isAppDataRestored) {
|
|
218
|
+
result.restoredAppDataPeers.push(localPeer.id);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const {
|
|
222
|
+
fixedProducersState,
|
|
223
|
+
fixedConsumersState,
|
|
224
|
+
missingProducers,
|
|
225
|
+
} = this.restoreTracksState(localPeer, clusterPeer);
|
|
226
|
+
|
|
227
|
+
result.fixedProducersState.push(...fixedProducersState);
|
|
228
|
+
result.fixedConsumersState.push(...fixedConsumersState);
|
|
229
|
+
result.missingProducers.push(...missingProducers);
|
|
201
230
|
});
|
|
202
231
|
|
|
203
232
|
this.#logger.info('Peers state restored', { case: 'restoreLocalState' });
|
|
233
|
+
|
|
234
|
+
return result;
|
|
204
235
|
}
|
|
205
236
|
|
|
206
|
-
private removeUnnecessaryProducers(localPeer: Peer, clusterPeer: PeerResponse):
|
|
237
|
+
private removeUnnecessaryProducers(localPeer: Peer, clusterPeer: PeerResponse): string[] {
|
|
238
|
+
const result: string[] = [];
|
|
207
239
|
const unnecessaryProducers = localPeer.getProducers()
|
|
208
240
|
.filter((lp) => !clusterPeer.producers.find((cp) => cp.id === lp.id));
|
|
209
241
|
unnecessaryProducers.forEach((producer) => {
|
|
210
242
|
localPeer.observer.safeEmit(MEDIASOUP_EVENTS.producerClose, producer);
|
|
243
|
+
result.push(producer.id);
|
|
211
244
|
this.#logger.info('Unnecessary producer removed', {
|
|
212
245
|
case: 'restoreLocalState',
|
|
213
246
|
removedProducerId: producer.id,
|
|
214
247
|
removedProducerPeerId: producer.peerId,
|
|
215
248
|
});
|
|
216
249
|
});
|
|
250
|
+
|
|
251
|
+
return result;
|
|
217
252
|
}
|
|
218
253
|
|
|
219
|
-
private restoreTracksState(localPeer: Peer, clusterPeer: PeerResponse):
|
|
254
|
+
private restoreTracksState(localPeer: Peer, clusterPeer: PeerResponse): RestoredTracksResult {
|
|
255
|
+
const result: RestoredTracksResult = {
|
|
256
|
+
missingProducers: [],
|
|
257
|
+
fixedProducersState: [],
|
|
258
|
+
fixedConsumersState: [],
|
|
259
|
+
};
|
|
260
|
+
|
|
220
261
|
clusterPeer.producers.forEach((clusterPeerProducer) => {
|
|
221
262
|
const localProducer = localPeer.producers.get(clusterPeerProducer.id);
|
|
222
263
|
if (!localProducer) {
|
|
223
264
|
localPeer.observer.safeEmit(MEDIASOUP_EVENTS.newProducer, clusterPeerProducer);
|
|
265
|
+
result.missingProducers.push(clusterPeerProducer.id);
|
|
224
266
|
this.#logger.info('Missing producer added to storage', {
|
|
225
267
|
case: 'restoreLocalState',
|
|
226
268
|
producerId: clusterPeerProducer.id,
|
|
@@ -239,6 +281,7 @@ class ChannelStateSynchronizer {
|
|
|
239
281
|
label: localProducer.label,
|
|
240
282
|
paused: localProducer.paused,
|
|
241
283
|
});
|
|
284
|
+
result.fixedProducersState.push(clusterPeerProducer.id);
|
|
242
285
|
|
|
243
286
|
this.#logger.info('Producer state fixed', {
|
|
244
287
|
case: 'restoreLocalState',
|
|
@@ -248,10 +291,11 @@ class ChannelStateSynchronizer {
|
|
|
248
291
|
}
|
|
249
292
|
|
|
250
293
|
const consumer = localPeer.tracks.get(localProducer.label);
|
|
251
|
-
if (consumer && consumer.consumerId && consumer.
|
|
294
|
+
if (consumer && consumer.consumerId && consumer.consumer?.paused !== clusterPeerProducer.paused) {
|
|
252
295
|
const { consumerId } = consumer;
|
|
253
296
|
const eventName = localProducer.paused ? MEDIASOUP_EVENTS.pauseConsumer : MEDIASOUP_EVENTS.resumeConsumer;
|
|
254
297
|
localPeer.observer.safeEmit(eventName, consumerId);
|
|
298
|
+
result.fixedConsumersState.push(consumerId);
|
|
255
299
|
this.#logger.info('Consumer state fixed', {
|
|
256
300
|
case: 'restoreLocalState',
|
|
257
301
|
consumerId,
|
|
@@ -260,12 +304,14 @@ class ChannelStateSynchronizer {
|
|
|
260
304
|
});
|
|
261
305
|
}
|
|
262
306
|
});
|
|
307
|
+
|
|
308
|
+
return result;
|
|
263
309
|
}
|
|
264
310
|
|
|
265
|
-
private restoreAppData(localPeer: Peer, clusterPeer: PeerResponse):
|
|
311
|
+
private restoreAppData(localPeer: Peer, clusterPeer: PeerResponse): boolean {
|
|
266
312
|
const isSameAppData = deepEqualObject(localPeer.appData, clusterPeer.appData);
|
|
267
313
|
if (isSameAppData) {
|
|
268
|
-
return;
|
|
314
|
+
return false;
|
|
269
315
|
}
|
|
270
316
|
|
|
271
317
|
localPeer.observer.emit(CHANNEL_EVENTS.updatePeerAppData, clusterPeer.appData);
|
|
@@ -274,6 +320,8 @@ class ChannelStateSynchronizer {
|
|
|
274
320
|
peerId: localPeer.id,
|
|
275
321
|
appData: clusterPeer.appData,
|
|
276
322
|
});
|
|
323
|
+
|
|
324
|
+
return true;
|
|
277
325
|
}
|
|
278
326
|
}
|
|
279
327
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface RestoredProducersStateResult {
|
|
2
|
+
removedProducers: string[];
|
|
3
|
+
fixedProducersState: string[];
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface RestoredTracksResult {
|
|
7
|
+
missingProducers: string[];
|
|
8
|
+
fixedProducersState: string[];
|
|
9
|
+
fixedConsumersState: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface RestoredLocalPeersStateResult extends RestoredTracksResult {
|
|
13
|
+
removedProducers: string[];
|
|
14
|
+
restoredAppDataPeers: string[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type RestoreChannelStateResult = {
|
|
18
|
+
removedPeers: string[];
|
|
19
|
+
missingPeers: string[];
|
|
20
|
+
} & RestoredProducersStateResult
|
|
21
|
+
& RestoredTracksResult
|
|
22
|
+
& RestoredLocalPeersStateResult;
|
|
@@ -17,7 +17,9 @@ import SocketIO from './network/Socket';
|
|
|
17
17
|
import LoadBalancerApiClient from './network/LoadBalancerClient';
|
|
18
18
|
import ChannelAudioObserverEventHandler from './handlers/ChannelAudioObserverEventHandler';
|
|
19
19
|
import ChannelStateSyncEventHandler from './handlers/ChannelStateSyncEventHandler';
|
|
20
|
-
import ChannelStateSynchronizer, {
|
|
20
|
+
import ChannelStateSynchronizer, {
|
|
21
|
+
ChannelStateSynchronizerParams,
|
|
22
|
+
} from './ChannelStateSynchronyzer/ChannelStateSynchronizer';
|
|
21
23
|
import IssueDetectorFactory from './IssueDetectorFactory';
|
|
22
24
|
|
|
23
25
|
/* eslint-disable class-methods-use-this */
|
package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyCheckResult.ts
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
missingPeers: string[];
|
|
3
|
-
missingConsumers: string[];
|
|
4
|
-
missingProducers: string[];
|
|
5
|
-
consumersWithInconsistentState: string[];
|
|
6
|
-
producersWithInconsistentState: string[];
|
|
7
|
-
peersWithInconsistentAppData: string[];
|
|
8
|
-
}
|
|
1
|
+
import { ChannelStateConsistencyCheckResultsParams } from './types';
|
|
9
2
|
|
|
10
3
|
class ChannelStateConsistencyCheckResult {
|
|
11
4
|
readonly missingPeers: string[];
|
|
12
5
|
|
|
13
|
-
readonly missingConsumers: string[];
|
|
14
|
-
|
|
15
6
|
readonly missingProducers: string[];
|
|
16
7
|
|
|
17
8
|
readonly consumersWithInconsistentState: string[];
|
|
@@ -22,7 +13,6 @@ class ChannelStateConsistencyCheckResult {
|
|
|
22
13
|
|
|
23
14
|
constructor(params: ChannelStateConsistencyCheckResultsParams) {
|
|
24
15
|
this.missingPeers = params.missingPeers;
|
|
25
|
-
this.missingConsumers = params.missingConsumers;
|
|
26
16
|
this.missingProducers = params.missingProducers;
|
|
27
17
|
this.consumersWithInconsistentState = params.consumersWithInconsistentState;
|
|
28
18
|
this.producersWithInconsistentState = params.producersWithInconsistentState;
|
|
@@ -31,7 +21,6 @@ class ChannelStateConsistencyCheckResult {
|
|
|
31
21
|
|
|
32
22
|
hasInconsistencyCases() {
|
|
33
23
|
return this.missingPeers.length > 0
|
|
34
|
-
|| this.missingConsumers.length > 0
|
|
35
24
|
|| this.missingProducers.length > 0
|
|
36
25
|
|| this.consumersWithInconsistentState.length > 0
|
|
37
26
|
|| this.producersWithInconsistentState.length > 0
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ChannelState,
|
|
3
|
-
ChannelStatePeer,
|
|
4
|
-
ChannelStateProducer,
|
|
5
|
-
} from '../../../types/channelStateSyncronizer';
|
|
1
|
+
import { ChannelState, ChannelStatePeer, ChannelStateProducer } from '../../../types/channelStateSyncronizer';
|
|
6
2
|
import ChannelStateConsistencyCheckResult from './ChannelStateConsistencyCheckResult';
|
|
7
3
|
|
|
8
4
|
interface ChannelStateConsistencyCheckerParams {
|
|
9
5
|
localState: ChannelState;
|
|
10
6
|
remoteState: ChannelState;
|
|
11
|
-
ignoreIds: string[];
|
|
12
7
|
}
|
|
13
8
|
|
|
14
9
|
class ChannelStateConsistencyChecker {
|
|
@@ -16,12 +11,8 @@ class ChannelStateConsistencyChecker {
|
|
|
16
11
|
|
|
17
12
|
private readonly remoteState: ChannelState;
|
|
18
13
|
|
|
19
|
-
private readonly ignoreIds: string[];
|
|
20
|
-
|
|
21
14
|
private missingPeers: string[] = [];
|
|
22
15
|
|
|
23
|
-
private missingConsumers: string[] = [];
|
|
24
|
-
|
|
25
16
|
private missingProducers: string[] = [];
|
|
26
17
|
|
|
27
18
|
private consumersWithInconsistentState: string[] = [];
|
|
@@ -33,16 +24,11 @@ class ChannelStateConsistencyChecker {
|
|
|
33
24
|
constructor(params: ChannelStateConsistencyCheckerParams) {
|
|
34
25
|
this.localState = params.localState;
|
|
35
26
|
this.remoteState = params.remoteState;
|
|
36
|
-
this.ignoreIds = params.ignoreIds;
|
|
37
27
|
}
|
|
38
28
|
|
|
39
29
|
check(): ChannelStateConsistencyCheckResult {
|
|
40
30
|
this.resetPreviousCheckResults();
|
|
41
31
|
this.remoteState.peers.forEach((remotePeer) => {
|
|
42
|
-
if (this.ignoreIds.includes(remotePeer.id)) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
32
|
const localPeer = this.findLocalPeerById(remotePeer.id);
|
|
47
33
|
if (!localPeer) {
|
|
48
34
|
this.missingPeers.push(remotePeer.id);
|
|
@@ -55,16 +41,8 @@ class ChannelStateConsistencyChecker {
|
|
|
55
41
|
}
|
|
56
42
|
|
|
57
43
|
remotePeer.producers.forEach((remoteProducer) => {
|
|
58
|
-
if (this.ignoreIds.includes(remoteProducer.id)) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
44
|
const localConsumer = this.findLocalConsumerByProducerId(localPeer, remoteProducer.id);
|
|
63
|
-
if (
|
|
64
|
-
localConsumer
|
|
65
|
-
&& !this.ignoreIds.includes(localConsumer.id)
|
|
66
|
-
&& localConsumer.paused !== remoteProducer.paused
|
|
67
|
-
) {
|
|
45
|
+
if (localConsumer && localConsumer.paused !== remoteProducer.paused) {
|
|
68
46
|
this.consumersWithInconsistentState.push(localConsumer.id);
|
|
69
47
|
}
|
|
70
48
|
|
|
@@ -73,10 +51,6 @@ class ChannelStateConsistencyChecker {
|
|
|
73
51
|
this.missingProducers.push(remoteProducer.id);
|
|
74
52
|
}
|
|
75
53
|
|
|
76
|
-
if (!localConsumer && !localProducer) {
|
|
77
|
-
this.missingConsumers.push(remoteProducer.id);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
54
|
if (!localProducer) {
|
|
81
55
|
return;
|
|
82
56
|
}
|
|
@@ -88,29 +62,19 @@ class ChannelStateConsistencyChecker {
|
|
|
88
62
|
});
|
|
89
63
|
});
|
|
90
64
|
|
|
91
|
-
|
|
65
|
+
return new ChannelStateConsistencyCheckResult({
|
|
92
66
|
missingPeers: this.missingPeers,
|
|
93
|
-
missingConsumers: this.missingConsumers,
|
|
94
67
|
missingProducers: this.missingProducers,
|
|
95
68
|
consumersWithInconsistentState: this.consumersWithInconsistentState,
|
|
96
69
|
producersWithInconsistentState: this.producersWithInconsistentState,
|
|
97
70
|
peersWithInconsistentAppData: this.peersWithInconsistentAppData,
|
|
98
71
|
});
|
|
99
|
-
|
|
100
|
-
return checkResults;
|
|
101
72
|
}
|
|
102
73
|
|
|
103
74
|
getMissingPeers(): string[] {
|
|
104
75
|
return this.missingPeers;
|
|
105
76
|
}
|
|
106
77
|
|
|
107
|
-
/**
|
|
108
|
-
* Contains list of remote producer ids for which local consumer is missing
|
|
109
|
-
*/
|
|
110
|
-
getMissingConsumers(): string[] {
|
|
111
|
-
return this.missingConsumers;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
78
|
getMissingProducers(): string[] {
|
|
115
79
|
return this.missingProducers;
|
|
116
80
|
}
|
|
@@ -141,7 +105,6 @@ class ChannelStateConsistencyChecker {
|
|
|
141
105
|
|
|
142
106
|
private resetPreviousCheckResults(): void {
|
|
143
107
|
this.missingPeers = [];
|
|
144
|
-
this.missingConsumers = [];
|
|
145
108
|
this.missingProducers = [];
|
|
146
109
|
this.consumersWithInconsistentState = [];
|
|
147
110
|
this.producersWithInconsistentState = [];
|