mirror of
https://github.com/vector-im/element-call.git
synced 2026-07-18 18:59:23 +00:00
fix: race initial publish and muting
This commit is contained in:
@@ -149,9 +149,7 @@ describe("Publisher", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe("Bug fix", () => {
|
describe("Bug fix", () => {
|
||||||
|
|
||||||
// There is a race condition when creating and publishing tracks while the mute state changes.
|
// There is a race condition when creating and publishing tracks while the mute state changes.
|
||||||
// This race condition could cause tracks to be published even though they are muted at the
|
// This race condition could cause tracks to be published even though they are muted at the
|
||||||
// beginning of a call coming from lobby.
|
// beginning of a call coming from lobby.
|
||||||
@@ -162,7 +160,7 @@ describe("Bug fix", () => {
|
|||||||
// If in the middle of that process the mute state changes:
|
// If in the middle of that process the mute state changes:
|
||||||
// - the `setMicrophoneEnabled` will be no-op because it is not aware of our created track and can't see any pending publication
|
// - the `setMicrophoneEnabled` will be no-op because it is not aware of our created track and can't see any pending publication
|
||||||
// - If start publication is requested it will publish the track even though there was a mute request.
|
// - If start publication is requested it will publish the track even though there was a mute request.
|
||||||
it.fails("wrongly publish tracks while muted", async () => {
|
it("wrongly publish tracks while muted", async () => {
|
||||||
const audioEnabled$ = new BehaviorSubject(true);
|
const audioEnabled$ = new BehaviorSubject(true);
|
||||||
const muteStates = {
|
const muteStates = {
|
||||||
audio: {
|
audio: {
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ export class Publisher {
|
|||||||
this.logger.error("Failed to create tracks", error);
|
this.logger.error("Failed to create tracks", error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// TODO why throw here? should we just do nothing?
|
||||||
throw Error("audio and video is false");
|
throw Error("audio and video is false");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,16 +185,32 @@ export class Publisher {
|
|||||||
|
|
||||||
for (const track of this.tracks$.value) {
|
for (const track of this.tracks$.value) {
|
||||||
this.logger.info("publish ", this.tracks$.value.length, "tracks");
|
this.logger.info("publish ", this.tracks$.value.length, "tracks");
|
||||||
// TODO: handle errors? Needs the signaling connection to be up, but it has some retries internally
|
|
||||||
// with a timeout.
|
|
||||||
await lkRoom.localParticipant.publishTrack(track).catch((error) => {
|
|
||||||
this.logger.error("Failed to publish track", error);
|
|
||||||
throw new FailToStartLivekitConnection(
|
|
||||||
error instanceof Error ? error.message : error,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
this.logger.info("published track ", track.kind, track.id);
|
|
||||||
|
|
||||||
|
// XXXX: Patch: Check if the track has been muted manually before publishing
|
||||||
|
// This is only a patch, the proper way would be to use livekit high-level enabled/disabled APIs
|
||||||
|
// or only use the low level create/publish APIs and have our own pending publication protection.
|
||||||
|
// Maybe we could change the livekit api to pre-load tracks without publishing them yet?
|
||||||
|
// Are we sure this is needed at all? What are the gains?
|
||||||
|
const isEnabled =
|
||||||
|
track.kind === Track.Kind.Audio
|
||||||
|
? this.muteStates.audio.enabled$.value
|
||||||
|
: this.muteStates.video.enabled$.value;
|
||||||
|
|
||||||
|
if (!isEnabled) {
|
||||||
|
// TODO should we also drop it?
|
||||||
|
// I believe the high-level LiveKit APIs will recreate a track?
|
||||||
|
await track.mute();
|
||||||
|
} else {
|
||||||
|
// TODO: handle errors? Needs the signaling connection to be up, but it has some retries internally
|
||||||
|
// with a timeout.
|
||||||
|
await lkRoom.localParticipant.publishTrack(track).catch((error) => {
|
||||||
|
this.logger.error("Failed to publish track", error);
|
||||||
|
throw new FailToStartLivekitConnection(
|
||||||
|
error instanceof Error ? error.message : error,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
this.logger.info("published track ", track.kind, track.id);
|
||||||
|
}
|
||||||
// TODO: check if the connection is still active? and break the loop if not?
|
// TODO: check if the connection is still active? and break the loop if not?
|
||||||
}
|
}
|
||||||
this._publishing$.next(true);
|
this._publishing$.next(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user