-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
abstract tx5 backend in prep for m̶o̶c̶k̶ mem backend (#105)
* abstract tx5 backend in prep for mock backend * Update crates/tx5/src/backend/go_pion.rs Co-authored-by: Callum Dunster <[email protected]> * address code review comments * address code review comment --------- Co-authored-by: Callum Dunster <[email protected]>
- Loading branch information
Showing
8 changed files
with
322 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
//! Backend modules usable by tx5. | ||
use std::io::Result; | ||
use std::sync::Arc; | ||
|
||
use futures::future::BoxFuture; | ||
|
||
use crate::{Config, PubKey}; | ||
use tx5_core::deps::serde_json; | ||
|
||
#[cfg(feature = "backend-go-pion")] | ||
mod go_pion; | ||
|
||
/// Backend modules usable by tx5. | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
pub enum BackendModule { | ||
#[cfg(feature = "backend-go-pion")] | ||
/// The Go Pion-based backend. | ||
GoPion, | ||
|
||
#[cfg(feature = "backend-webrtc-rs")] | ||
/// The Webrtc-RS-based backend. | ||
WebrtcRs, | ||
|
||
/// The mock backend. | ||
Mock, | ||
} | ||
|
||
impl Default for BackendModule { | ||
#[allow(unreachable_code)] | ||
fn default() -> Self { | ||
#[cfg(feature = "backend-go-pion")] | ||
return Self::GoPion; | ||
#[cfg(feature = "backend-webrtc-rs")] | ||
return Self::WebrtcRs; | ||
Self::Mock | ||
} | ||
} | ||
|
||
impl BackendModule { | ||
/// Get a default version of the module-specific config. | ||
pub fn default_config(&self) -> serde_json::Value { | ||
match self { | ||
#[cfg(feature = "backend-go-pion")] | ||
Self::GoPion => go_pion::default_config(), | ||
#[cfg(feature = "backend-webrtc-rs")] | ||
Self::WebrtcRs => todo!(), | ||
Self::Mock => serde_json::json!({}), | ||
} | ||
} | ||
|
||
/// Connect a new backend module endpoint. | ||
pub async fn connect( | ||
&self, | ||
url: &str, | ||
listener: bool, | ||
config: &Arc<Config>, | ||
) -> Result<(DynBackEp, DynBackEpRecvCon)> { | ||
match self { | ||
#[cfg(feature = "backend-go-pion")] | ||
Self::GoPion => go_pion::connect(config, url, listener).await, | ||
#[cfg(feature = "backend-webrtc-rs")] | ||
Self::WebrtcRs => todo!(), | ||
Self::Mock => todo!(), | ||
} | ||
} | ||
} | ||
|
||
/// Backend connection. | ||
pub trait BackCon: 'static + Send + Sync { | ||
/// Send data over this backend connection. | ||
fn send(&self, data: Vec<u8>) -> BoxFuture<'_, Result<()>>; | ||
|
||
/// Get the pub_key identifying this connection. | ||
fn pub_key(&self) -> &PubKey; | ||
|
||
/// Returns `true` if we successfully connected over webrtc. | ||
// TODO - this isn't good encapsulation | ||
fn is_using_webrtc(&self) -> bool; | ||
|
||
/// Get connection statistics. | ||
// TODO - this isn't good encapsulation | ||
fn get_stats(&self) -> tx5_connection::ConnStats; | ||
} | ||
|
||
/// Trait-object version of backend connection. | ||
pub type DynBackCon = Arc<dyn BackCon + 'static + Send + Sync>; | ||
|
||
/// Backend connection receiver. | ||
pub trait BackConRecvData: 'static + Send { | ||
/// Receive data from this backend connection. | ||
fn recv(&mut self) -> BoxFuture<'_, Option<Vec<u8>>>; | ||
} | ||
|
||
/// Trait-object version of backend connection receiver. | ||
pub type DynBackConRecvData = Box<dyn BackConRecvData + 'static + Send>; | ||
|
||
/// Pending connection. | ||
pub trait BackWaitCon: 'static + Send { | ||
/// Wait for the connection | ||
fn wait( | ||
&mut self, | ||
// TODO - this isn't good encapsulation | ||
recv_limit: Arc<tokio::sync::Semaphore>, | ||
) -> BoxFuture<'static, Result<(DynBackCon, DynBackConRecvData)>>; | ||
|
||
/// Get the pub_key identifying this connection. | ||
fn pub_key(&self) -> &PubKey; | ||
} | ||
|
||
/// Trait-object version of backend wait con. | ||
pub type DynBackWaitCon = Box<dyn BackWaitCon + 'static + Send>; | ||
|
||
/// Backend endpoint. | ||
pub trait BackEp: 'static + Send + Sync { | ||
/// Establish an outgoing connection from this backend endpoint. | ||
fn connect(&self, pub_key: PubKey) | ||
-> BoxFuture<'_, Result<DynBackWaitCon>>; | ||
|
||
/// Get the pub_key identifying this endpoint. | ||
fn pub_key(&self) -> &PubKey; | ||
} | ||
|
||
/// Trait-object version of backend endpoint. | ||
pub type DynBackEp = Arc<dyn BackEp + 'static + Send + Sync>; | ||
|
||
/// Backend endpoint receiver. | ||
pub trait BackEpRecvCon: 'static + Send { | ||
/// Receive incoming connection from this backend endpoint. | ||
fn recv(&mut self) -> BoxFuture<'_, Option<DynBackWaitCon>>; | ||
} | ||
|
||
/// Trait-object version of backend endpoint receiver. | ||
pub type DynBackEpRecvCon = Box<dyn BackEpRecvCon + 'static + Send>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
//! go pion backend | ||
use super::*; | ||
use crate::Config; | ||
|
||
struct GoCon(tx5_connection::FramedConn); | ||
|
||
impl BackCon for GoCon { | ||
fn send(&self, data: Vec<u8>) -> BoxFuture<'_, Result<()>> { | ||
Box::pin(async { self.0.send(data).await }) | ||
} | ||
|
||
fn pub_key(&self) -> &PubKey { | ||
self.0.pub_key() | ||
} | ||
|
||
fn is_using_webrtc(&self) -> bool { | ||
self.0.is_using_webrtc() | ||
} | ||
|
||
fn get_stats(&self) -> tx5_connection::ConnStats { | ||
self.0.get_stats() | ||
} | ||
} | ||
|
||
struct GoConRecvData(tx5_connection::FramedConnRecv); | ||
|
||
impl BackConRecvData for GoConRecvData { | ||
fn recv(&mut self) -> BoxFuture<'_, Option<Vec<u8>>> { | ||
Box::pin(async { self.0.recv().await }) | ||
} | ||
} | ||
|
||
struct GoWaitCon { | ||
pub_key: PubKey, | ||
con: Option<Arc<tx5_connection::Conn>>, | ||
con_recv: Option<tx5_connection::ConnRecv>, | ||
} | ||
|
||
impl BackWaitCon for GoWaitCon { | ||
fn wait( | ||
&mut self, | ||
recv_limit: Arc<tokio::sync::Semaphore>, | ||
) -> BoxFuture<'static, Result<(DynBackCon, DynBackConRecvData)>> { | ||
let con = self.con.take(); | ||
let con_recv = self.con_recv.take(); | ||
Box::pin(async move { | ||
let (con, con_recv) = match (con, con_recv) { | ||
(Some(con), Some(con_recv)) => (con, con_recv), | ||
_ => return Err(std::io::Error::other("already awaited")), | ||
}; | ||
|
||
con.ready().await; | ||
|
||
let (con, con_recv) = | ||
tx5_connection::FramedConn::new(con, con_recv, recv_limit) | ||
.await?; | ||
|
||
let con: DynBackCon = Arc::new(GoCon(con)); | ||
let con_recv: DynBackConRecvData = | ||
Box::new(GoConRecvData(con_recv)); | ||
|
||
Ok((con, con_recv)) | ||
}) | ||
} | ||
|
||
fn pub_key(&self) -> &PubKey { | ||
&self.pub_key | ||
} | ||
} | ||
|
||
struct GoEp(tx5_connection::Hub); | ||
|
||
impl BackEp for GoEp { | ||
fn connect( | ||
&self, | ||
pub_key: PubKey, | ||
) -> BoxFuture<'_, Result<DynBackWaitCon>> { | ||
Box::pin(async { | ||
let (con, con_recv) = self.0.connect(pub_key).await?; | ||
let pub_key = con.pub_key().clone(); | ||
let wc: DynBackWaitCon = Box::new(GoWaitCon { | ||
pub_key, | ||
con: Some(con), | ||
con_recv: Some(con_recv), | ||
}); | ||
Ok(wc) | ||
}) | ||
} | ||
|
||
fn pub_key(&self) -> &PubKey { | ||
self.0.pub_key() | ||
} | ||
} | ||
|
||
struct GoEpRecvCon(tx5_connection::HubRecv); | ||
|
||
impl BackEpRecvCon for GoEpRecvCon { | ||
fn recv(&mut self) -> BoxFuture<'_, Option<DynBackWaitCon>> { | ||
Box::pin(async { | ||
let (con, con_recv) = self.0.accept().await?; | ||
let pub_key = con.pub_key().clone(); | ||
let wc: DynBackWaitCon = Box::new(GoWaitCon { | ||
pub_key, | ||
con: Some(con), | ||
con_recv: Some(con_recv), | ||
}); | ||
Some(wc) | ||
}) | ||
} | ||
} | ||
|
||
/// Get a default version of the module-specific config. | ||
pub fn default_config() -> serde_json::Value { | ||
serde_json::json!({}) | ||
} | ||
|
||
/// Connect a new backend based on the tx5-go-pion backend. | ||
pub async fn connect( | ||
config: &Arc<Config>, | ||
url: &str, | ||
listener: bool, | ||
) -> Result<(DynBackEp, DynBackEpRecvCon)> { | ||
let webrtc_config = config.initial_webrtc_config.clone().into_bytes(); | ||
let sig_config = tx5_connection::tx5_signal::SignalConfig { | ||
listener, | ||
allow_plain_text: config.signal_allow_plain_text, | ||
//max_connections: config.connection_count_max as usize, | ||
max_idle: config.timeout, | ||
..Default::default() | ||
}; | ||
let (hub, hub_recv) = | ||
tx5_connection::Hub::new(webrtc_config, url, Arc::new(sig_config)) | ||
.await?; | ||
let ep: DynBackEp = Arc::new(GoEp(hub)); | ||
let ep_recv: DynBackEpRecvCon = Box::new(GoEpRecvCon(hub_recv)); | ||
Ok((ep, ep_recv)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.