Internal SessionEvents to avoid confusion with the RoomEvents

This commit is contained in:
Théo Monnom
2022-12-27 20:57:35 +01:00
parent 5f290de593
commit 9d05259c5a
4 changed files with 118 additions and 75 deletions
@@ -2,7 +2,8 @@ use crate::proto::{data_packet, DataPacket, UserPacket};
use crate::room::participant::{
impl_participant_trait, ParticipantInternalTrait, ParticipantShared, ParticipantTrait,
};
use crate::room::{RoomError, RoomEmitter};
use crate::room::room_session::SessionEmitter;
use crate::room::RoomError;
use crate::rtc_engine::RTCEngine;
#[derive(Debug)]
@@ -18,10 +19,10 @@ impl LocalParticipant {
identity: ParticipantIdentity,
name: String,
metadata: String,
room_emitter: RoomEmitter,
internal_tx: SessionEmitter,
) -> Self {
Self {
shared: ParticipantShared::new(sid, identity, name, metadata, room_emitter),
shared: ParticipantShared::new(sid, identity, name, metadata, internal_tx),
rtc_engine,
}
}
@@ -3,6 +3,7 @@ use crate::room::id::{ParticipantIdentity, ParticipantSid, TrackSid};
use crate::room::participant::local_participant::LocalParticipant;
use crate::room::participant::remote_participant::RemoteParticipant;
use crate::room::publication::{TrackPublication, TrackPublicationTrait};
use crate::room::room_session::SessionEmitter;
use livekit_utils::enum_dispatch;
use parking_lot::{Mutex, RwLock};
use std::collections::HashMap;
@@ -18,7 +19,7 @@ pub(super) struct ParticipantShared {
pub(super) name: Mutex<String>,
pub(super) metadata: Mutex<String>,
pub(super) tracks: RwLock<HashMap<TrackSid, TrackPublication>>,
pub(super) room_emitter: RoomEmitter,
pub(super) internal_tx: SessionEmitter,
}
impl ParticipantShared {
@@ -27,7 +28,7 @@ impl ParticipantShared {
identity: ParticipantIdentity,
name: String,
metadata: String,
room_emitter: RoomEmitter,
internal_tx: SessionEmitter,
) -> Self {
Self {
sid: Mutex::new(sid),
@@ -35,7 +36,7 @@ impl ParticipantShared {
name: Mutex::new(name),
metadata: Mutex::new(metadata),
tracks: Default::default(),
room_emitter
internal_tx,
}
}
@@ -7,16 +7,18 @@ use crate::room::publication::{
RemoteTrackPublication, TrackPublication, TrackPublicationInternalTrait, TrackPublicationTrait,
};
use crate::room::room_session::RoomSession;
use crate::room::room_session::SessionEmitter;
use crate::room::room_session::SessionEvent;
use crate::room::track::remote_audio_track::RemoteAudioTrack;
use crate::room::track::remote_track::RemoteTrackHandle;
use crate::room::track::remote_video_track::RemoteVideoTrack;
use crate::room::track::{TrackKind, TrackTrait};
use crate::room::{RoomEmitter, RoomEvent, TrackError};
use crate::room::{RoomEvent, TrackError};
use livekit_webrtc::media_stream::MediaStreamTrackHandle;
use std::collections::HashSet;
use std::time::Duration;
use tokio::time::{sleep, timeout};
use tracing::{debug, debug_span, error, instrument, Instrument, Level};
use tokio::time::timeout;
use tracing::{debug, error, instrument, Level};
use super::ParticipantTrait;
@@ -33,10 +35,10 @@ impl RemoteParticipant {
identity: ParticipantIdentity,
name: String,
metadata: String,
room_emitter: RoomEmitter,
internal_tx: SessionEmitter,
) -> Self {
Self {
shared: ParticipantShared::new(sid, identity, name, metadata, room_emitter),
shared: ParticipantShared::new(sid, identity, name, metadata, internal_tx),
}
}
@@ -50,10 +52,9 @@ impl RemoteParticipant {
})
}
#[instrument(level = Level::DEBUG, skip(room_session))]
#[instrument(level = Level::DEBUG)]
pub(crate) async fn add_subscribed_media_track(
self: Arc<Self>,
room_session: RoomSession,
sid: TrackSid,
media_track: MediaStreamTrackHandle,
) {
@@ -67,7 +68,7 @@ impl RemoteParticipant {
return publication;
}
tokio::task::yield_now();
tokio::task::yield_now().await;
}
}
};
@@ -108,30 +109,28 @@ impl RemoteParticipant {
.add_track_publication(TrackPublication::Remote(remote_publication.clone()));
track.start();
self.shared.room_emitter.send(RoomEvent::TrackSubscribed {
track: track,
publication: remote_publication,
participant: self.clone(),
});
self.shared
.internal_tx
.send(SessionEvent::Room(RoomEvent::TrackSubscribed {
track: track,
publication: remote_publication,
participant: self.clone(),
}));
} else {
error!("could not find published track with sid: {:?}", sid);
self.shared
.room_emitter
.send(RoomEvent::TrackSubscriptionFailed {
.internal_tx
.send(SessionEvent::Room(RoomEvent::TrackSubscriptionFailed {
sid: sid.clone(),
error: TrackError::TrackNotFound(sid.clone().to_string()),
participant: self.clone(),
});
}));
}
}
#[instrument(level = Level::DEBUG, skip(room_session))]
pub(crate) async fn update_tracks(
self: Arc<Self>,
room_session: RoomSession,
tracks: Vec<TrackInfo>,
) {
#[instrument(level = Level::DEBUG)]
pub(crate) async fn update_tracks(self: Arc<Self>, tracks: Vec<TrackInfo>) {
let mut valid_tracks = HashSet::<TrackSid>::new();
for track in tracks {
@@ -143,10 +142,12 @@ impl RemoteParticipant {
.add_track_publication(TrackPublication::Remote(publication.clone()));
// This is a new track, fire publish events
self.shared.room_emitter.send(RoomEvent::TrackPublished {
publication: publication.clone(),
participant: self.clone(),
});
self.shared
.internal_tx
.send(SessionEvent::Room(RoomEvent::TrackPublished {
publication: publication.clone(),
participant: self.clone(),
}));
}
valid_tracks.insert(track.sid.into());
+83 -43
View File
@@ -10,10 +10,19 @@ use parking_lot::{Mutex, RwLock};
use std::collections::HashMap;
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc;
use tokio::sync::mpsc;
use tokio::sync::oneshot;
use tokio::task::JoinHandle;
use tracing::{error, instrument, Level};
pub(crate) type SessionEmitter = mpsc::UnboundedSender<SessionEvent>;
pub(crate) type SessionEvents = mpsc::UnboundedReceiver<SessionEvent>;
/// Used internally for participants and tracks
pub(crate) enum SessionEvent {
Room(RoomEvent), // Send a public event
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum ConnectionState {
Disconnected,
@@ -43,7 +52,7 @@ struct SessionInner {
participants: RwLock<HashMap<ParticipantSid, Arc<RemoteParticipant>>>,
rtc_engine: Arc<RTCEngine>,
local_participant: Arc<LocalParticipant>,
room_emitter: RoomEmitter,
internal_tx: SessionEmitter,
}
#[derive(Debug)]
@@ -68,6 +77,7 @@ impl SessionHandle {
.connect(url, token, SignalOptions::default())
.await?;
let (internal_tx, internal_rx) = mpsc::unbounded_channel();
let join_response = rtc_engine.join_response().unwrap();
let pi = join_response.participant.unwrap().clone();
let local_participant = Arc::new(LocalParticipant::new(
@@ -76,8 +86,9 @@ impl SessionHandle {
pi.identity.into(),
pi.name,
pi.metadata,
room_emitter.clone(),
internal_tx.clone(),
));
let room_info = join_response.room.unwrap();
let inner = Arc::new(SessionInner {
state: AtomicU8::new(ConnectionState::Disconnected as u8),
@@ -86,7 +97,7 @@ impl SessionHandle {
participants: Default::default(),
rtc_engine,
local_participant,
room_emitter,
internal_tx,
});
for pi in join_response.other_participants {
@@ -95,13 +106,16 @@ impl SessionHandle {
inner.create_participant(pi.sid.into(), pi.identity.into(), pi.name, pi.metadata)
};
participant.update_info(pi.clone());
participant
.update_tracks(RoomSession::from(inner.clone()), pi.tracks)
.await;
participant.update_tracks(pi.tracks).await;
}
let (close_emitter, close_receiver) = oneshot::channel();
let session_task = tokio::spawn(inner.clone().room_task(engine_events, close_receiver));
let session_task = tokio::spawn(inner.clone().room_task(
engine_events,
internal_rx,
close_receiver,
room_emitter,
));
inner
.update_connection_state(ConnectionState::Connected)
@@ -161,18 +175,32 @@ impl SessionInner {
async fn room_task(
self: Arc<Self>,
mut engine_events: EngineEvents,
mut internal_rx: SessionEvents,
mut close_receiver: oneshot::Receiver<()>,
room_emitter: RoomEmitter,
) {
loop {
tokio::select! {
biased;
res = internal_rx.recv() => {
match res {
Some(event) => {
if let Err(err) = self.on_internal_event(event, &room_emitter).await {
error!("failed to handle internal event: {:?}", err);
}
},
_ => panic!("internal_rx has been closed unexpectedly")
};
}
res = engine_events.recv() => {
if let Some(event) = res {
if let Err(err) = self.on_engine_event(event).await {
error!("failed to handle engine event: {:?}", err);
}
} else {
panic!("engine_events has been closed unexpectedly");
}
match res {
Some(event) => {
if let Err(err) = self.on_engine_event(event).await {
error!("failed to handle engine event: {:?}", err);
}
},
_ => panic!("engine_events has been closed unexpectedly")
};
},
_ = &mut close_receiver => {
break;
@@ -181,6 +209,27 @@ impl SessionInner {
}
}
async fn on_internal_event(
&self,
event: SessionEvent,
room_emitter: &RoomEmitter,
) -> EngineResult<()> {
match event {
SessionEvent::Room(event) => {
if self.state.load(Ordering::Acquire) != ConnectionState::Connected as u8
&& matches!(event, RoomEvent::TrackPublished { .. })
{
return Ok(()); // Ignore the event
}
// Forward the event to the public channel
let _ = room_emitter.send(event);
}
}
Ok(())
}
#[instrument(level = Level::DEBUG)]
async fn on_engine_event(self: &Arc<Self>, event: EngineEvent) -> RoomResult<()> {
match event {
@@ -188,7 +237,7 @@ impl SessionInner {
EngineEvent::MediaTrack {
track,
stream,
receiver,
receiver: _,
} => {
let stream_id = stream.id();
let lk_stream_id = unpack_stream_id(&stream_id);
@@ -200,23 +249,14 @@ impl SessionInner {
}
let (participant_sid, track_sid) = lk_stream_id.unwrap();
let track_sid = track_sid.to_owned().into();
let remote_participant = self.get_participant(&participant_sid.to_string().into());
if let Some(remote_participant) = remote_participant {
tokio::spawn({
let session_inner = self.clone();
{
let track_sid = track_sid.to_owned().into();
async move {
remote_participant
.add_subscribed_media_track(
RoomSession::from(session_inner),
track_sid,
track,
)
.await;
}
}
tokio::spawn(async move {
remote_participant
.add_subscribed_media_track(track_sid, track)
.await;
});
} else {
// The server should send participant updates before sending a new offer
@@ -257,8 +297,8 @@ impl SessionInner {
self.state.store(state as u8, Ordering::Release);
let _ = self
.room_emitter
.send(RoomEvent::ConnectionStateChanged(state));
.internal_tx
.send(SessionEvent::Room(RoomEvent::ConnectionStateChanged(state)));
}
/// Update the participants inside a Room.
@@ -283,9 +323,7 @@ impl SessionInner {
} else {
// Participant is already connected, update the it
remote_participant.update_info(pi.clone());
remote_participant
.update_tracks(RoomSession::from(self.clone()), pi.tracks)
.await;
remote_participant.update_tracks(pi.tracks).await;
}
} else {
// Create a new participant
@@ -295,13 +333,13 @@ impl SessionInner {
};
let _ = self
.room_emitter
.send(RoomEvent::ParticipantConnected(remote_participant.clone()));
.internal_tx
.send(SessionEvent::Room(RoomEvent::ParticipantConnected(
remote_participant.clone(),
)));
remote_participant.update_info(pi.clone());
remote_participant
.update_tracks(RoomSession::from(self.clone()), pi.tracks)
.await;
remote_participant.update_tracks(pi.tracks).await;
}
}
}
@@ -313,9 +351,11 @@ impl SessionInner {
self.participants.write().remove(&remote_participant.sid());
// TODO(theomonnom): Unpublish all tracks
let _ = self.room_emitter.send(RoomEvent::ParticipantDisconnected(
remote_participant.clone(),
));
let _ = self
.internal_tx
.send(SessionEvent::Room(RoomEvent::ParticipantDisconnected(
remote_participant.clone(),
)));
}
/// Create a new participant
@@ -332,7 +372,7 @@ impl SessionInner {
identity,
name,
metadata,
self.room_emitter.clone(),
self.internal_tx.clone(),
));
self.participants.write().insert(sid, p.clone());