clean traits

This commit is contained in:
François Michel 2023-07-12 12:43:50 +00:00
parent 94b8b55ea6
commit 880079e142
6 changed files with 59 additions and 40 deletions

View File

@ -1,4 +1,4 @@
use moq_generic_transport::{SendStream, RecvStream, BidiStream, SendStreamUnframed}; use moq_generic_transport::{SendStream, RecvStream, BidiStream, SendStreamUnframed, Connection};
use moq_transport::{Decode, DecodeError, Encode, Message}; use moq_transport::{Decode, DecodeError, Encode, Message};
use bytes::{Buf, BytesMut}; use bytes::{Buf, BytesMut};
@ -9,12 +9,12 @@ use std::sync::Arc;
use tokio::sync::Mutex; use tokio::sync::Mutex;
pub struct Control<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S>> { pub struct Control<B: BidiStream> {
sender: ControlSend<B::SendStream>, sender: ControlSend<B>,
recver: ControlRecv<B::RecvStream>, recver: ControlRecv<B::RecvStream>,
} }
impl<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S>> Control<S, B> { impl<B: BidiStream> Control<B>{
pub(crate) fn new(stream: Box<B>) -> Self { pub(crate) fn new(stream: Box<B>) -> Self {
let (sender, recver) = stream.split(); let (sender, recver) = stream.split();
let sender = ControlSend::new(Box::new(sender)); let sender = ControlSend::new(Box::new(sender));
@ -23,7 +23,7 @@ impl<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S>> Control<
Self { sender, recver } Self { sender, recver }
} }
pub fn split(self) -> (ControlSend<B::SendStream>, ControlRecv<B::RecvStream>) { pub fn split(self) -> (ControlSend<B>, ControlRecv<B::RecvStream>) {
(self.sender, self.recver) (self.sender, self.recver)
} }
@ -36,13 +36,13 @@ impl<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S>> Control<
} }
} }
pub struct ControlSend<S> { pub struct ControlSend<B: BidiStream> {
stream: Box<S>, stream: Box<B::SendStream>,
buf: BytesMut, // reuse a buffer to encode messages. buf: BytesMut, // reuse a buffer to encode messages.
} }
impl<S: SendStream + SendStreamUnframed> ControlSend<S> { impl<B: BidiStream> ControlSend<B> {
pub fn new(inner: Box<S>) -> Self { pub fn new(inner: Box<B::SendStream>) -> Self {
Self { Self {
buf: BytesMut::new(), buf: BytesMut::new(),
stream: inner, stream: inner,
@ -63,10 +63,9 @@ impl<S: SendStream + SendStreamUnframed> ControlSend<S> {
} }
// Helper that lets multiple threads send control messages. // Helper that lets multiple threads send control messages.
pub fn share(self) -> ControlShared<S> { pub fn share(self) -> ControlShared<B> {
ControlShared { ControlShared {
stream: Arc::new(Mutex::new(self)), stream: Arc::new(Mutex::new(self)),
_marker: PhantomData,
} }
} }
} }
@ -74,12 +73,11 @@ impl<S: SendStream + SendStreamUnframed> ControlSend<S> {
// Helper that allows multiple threads to send control messages. // Helper that allows multiple threads to send control messages.
// There's no equivalent for receiving since only one thread should be receiving at a time. // There's no equivalent for receiving since only one thread should be receiving at a time.
#[derive(Clone)] #[derive(Clone)]
pub struct ControlShared<S: SendStream + SendStreamUnframed> { pub struct ControlShared<B: BidiStream> {
stream: Arc<Mutex<ControlSend<S>>>, stream: Arc<Mutex<ControlSend<B>>>,
_marker: PhantomData<S>
} }
impl<S: SendStream + SendStreamUnframed> ControlShared<S> { impl<B: BidiStream> ControlShared<B> {
pub async fn send<T: Into<Message>>(&mut self, msg: T) -> anyhow::Result<()> { pub async fn send<T: Into<Message>>(&mut self, msg: T) -> anyhow::Result<()> {
let mut stream = self.stream.lock().await; let mut stream = self.stream.lock().await;
stream.send(msg).await stream.send(msg).await

View File

@ -42,14 +42,14 @@ use super::{Control, Objects};
// } // }
pub struct Session<S: SendStream + SendStreamUnframed, R: RecvStream + Send, B: BidiStream<SendStream = S, RecvStream = R>, C: Connection<SendStream = S, RecvStream = R, BidiStream = B> + Send> { pub struct Session<C: Connection + Send> {
pub control: Control<S, C::BidiStream>, pub control: Control<C::BidiStream>,
pub objects: Objects<C>, pub objects: Objects<C>,
} }
impl<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S, RecvStream = R>, R: RecvStream + Send + 'static, C: Connection<SendStream = S, RecvStream = R, BidiStream = B> + Send> Session<S, R, B, C> { impl<R: RecvStream + 'static, C: Connection<RecvStream = R> + Send> Session<C> {
pub async fn accept(control_stream: Box<C::BidiStream>, connection: Box<C>) -> anyhow::Result<AcceptSetup<S, R, B, C>> { pub async fn accept(control_stream: Box<C::BidiStream>, connection: Box<C>) -> anyhow::Result<AcceptSetup<C>> {
let mut control = Control::new(control_stream); let mut control = Control::new(control_stream);
let objects = Objects::new(std::sync::Arc::new(std::sync::Mutex::new(connection))); let objects = Objects::new(std::sync::Arc::new(std::sync::Mutex::new(connection)));
@ -60,26 +60,26 @@ impl<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S, RecvStrea
Ok(AcceptSetup { setup_client, control, objects }) Ok(AcceptSetup { setup_client, control, objects })
} }
pub fn split(self) -> (Control<B::SendStream, C::BidiStream>, Objects<C>) { pub fn split(self) -> (Control<C::BidiStream>, Objects<C>) {
(self.control, self.objects) (self.control, self.objects)
} }
} }
pub struct AcceptSetup<S: SendStream + SendStreamUnframed, R: RecvStream + Send, B: BidiStream<SendStream = S, RecvStream = R>, C: Connection<SendStream = S, RecvStream = R, BidiStream = B> + Send> { pub struct AcceptSetup<C: Connection + Send> {
setup_client: SetupClient, setup_client: SetupClient,
control: Control<S, C::BidiStream>, control: Control<C::BidiStream>,
objects: Objects<C>, objects: Objects<C>,
} }
impl<S: SendStream + SendStreamUnframed, R: RecvStream + Send, B: BidiStream<SendStream = S, RecvStream = R>, C: Connection<SendStream = S, RecvStream = R, BidiStream = B> + Send> AcceptSetup<S, R, B, C> { impl<C: Connection + Send> AcceptSetup<C> {
// Return the setup message we received. // Return the setup message we received.
pub fn setup(&self) -> &SetupClient { pub fn setup(&self) -> &SetupClient {
&self.setup_client &self.setup_client
} }
// Accept the session with our own setup message. // Accept the session with our own setup message.
pub async fn accept(mut self, setup_server: SetupServer) -> anyhow::Result<Session<S, R, B, C>> { pub async fn accept(mut self, setup_server: SetupServer) -> anyhow::Result<Session<C>> {
self.control.send(setup_server).await?; self.control.send(setup_server).await?;
Ok(Session { Ok(Session {
control: self.control, control: self.control,

View File

@ -1,4 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::marker::PhantomData;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time; use std::time;
@ -19,7 +20,7 @@ use crate::model::{broadcast, segment, track};
use crate::source::Source; use crate::source::Source;
// TODO experiment with making this Clone, so every task can have its own copy. // TODO experiment with making this Clone, so every task can have its own copy.
pub struct Session<S: SendStream + SendStreamUnframed, R: RecvStream + Send, B: BidiStream<SendStream = S, RecvStream = R>, C: Connection<SendStream = S, RecvStream = R, BidiStream = B> + Send> { pub struct Session<R: RecvStream + Send, C: Connection + Send> {
// Used to receive objects. // Used to receive objects.
objects: RecvObjects<C>, objects: RecvObjects<C>,
@ -37,9 +38,10 @@ pub struct Session<S: SendStream + SendStreamUnframed, R: RecvStream + Send, B:
// Tasks we are currently serving. // Tasks we are currently serving.
run_segments: JoinSet<anyhow::Result<()>>, // receiving objects run_segments: JoinSet<anyhow::Result<()>>, // receiving objects
_marker: PhantomData<R>,
} }
impl<Bu: Buf + Send, S: SendStream + SendStreamUnframed, R: RecvStream<Buf = Bu> + Send + 'static, B: BidiStream<SendStream = S, RecvStream = R>, C: Connection<SendStream = S, RecvStream = R, BidiStream = B> + Send> Session<S, R, B, C> { impl<R: RecvStream + Send + 'static, C: Connection<RecvStream = R> + Send> Session<R, C> {
pub fn new( pub fn new(
objects: RecvObjects<C>, objects: RecvObjects<C>,
control: control::Component<control::Contribute>, control: control::Component<control::Contribute>,
@ -52,6 +54,7 @@ impl<Bu: Buf + Send, S: SendStream + SendStreamUnframed, R: RecvStream<Buf = Bu>
broadcasts: HashMap::new(), broadcasts: HashMap::new(),
publishers: Publishers::new(), publishers: Publishers::new(),
run_segments: JoinSet::new(), run_segments: JoinSet::new(),
_marker: PhantomData,
} }
} }
@ -179,7 +182,7 @@ impl<Bu: Buf + Send, S: SendStream + SendStreamUnframed, R: RecvStream<Buf = Bu>
} }
} }
impl<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S, RecvStream = R>, R: RecvStream + Send, C: Connection<SendStream = S, RecvStream = R, BidiStream = B> + Send> Drop for Session<S, R, B, C> { impl<R: RecvStream + Send, C: Connection + Send> Drop for Session<R, C> {
fn drop(&mut self) { fn drop(&mut self) {
// Unannounce all broadcasts we have announced. // Unannounce all broadcasts we have announced.
// TODO make this automatic so we can't screw up? // TODO make this automatic so we can't screw up?

View File

@ -4,15 +4,15 @@ use tokio::sync::mpsc;
use moq_transport::{Announce, AnnounceError, AnnounceOk, Message, Subscribe, SubscribeError, SubscribeOk}; use moq_transport::{Announce, AnnounceError, AnnounceOk, Message, Subscribe, SubscribeError, SubscribeOk};
use moq_transport_trait::Control; use moq_transport_trait::Control;
pub struct Main<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S>> { pub struct Main<B: BidiStream> {
control: Control<S, B>, control: Control<B>,
outgoing: mpsc::Receiver<Message>, outgoing: mpsc::Receiver<Message>,
contribute: mpsc::Sender<Contribute>, contribute: mpsc::Sender<Contribute>,
distribute: mpsc::Sender<Distribute>, distribute: mpsc::Sender<Distribute>,
} }
impl<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S>> Main <S, B> { impl<B: BidiStream> Main <B> {
pub async fn run(mut self) -> anyhow::Result<()> { pub async fn run(mut self) -> anyhow::Result<()> {
loop { loop {
tokio::select! { tokio::select! {
@ -52,7 +52,7 @@ impl<T> Component<T> {
} }
// Splits a control stream into two components, based on if it's a message for contribution or distribution. // Splits a control stream into two components, based on if it's a message for contribution or distribution.
pub fn split<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S>>(control: Control<S, B>) -> (Main<S, B>, Component<Contribute>, Component<Distribute>) { pub fn split<S: SendStream + SendStreamUnframed, B: BidiStream<SendStream = S>>(control: Control<B>) -> (Main<B>, Component<Contribute>, Component<Distribute>) {
let (outgoing_tx, outgoing_rx) = mpsc::channel(1); let (outgoing_tx, outgoing_rx) = mpsc::channel(1);
let (contribute_tx, contribute_rx) = mpsc::channel(1); let (contribute_tx, contribute_rx) = mpsc::channel(1);
let (distribute_tx, distribute_rx) = mpsc::channel(1); let (distribute_tx, distribute_rx) = mpsc::channel(1);

View File

@ -1,3 +1,5 @@
use std::marker::PhantomData;
use anyhow::Context; use anyhow::Context;
use bytes::Buf; use bytes::Buf;
@ -11,7 +13,7 @@ use moq_transport_trait::SendObjects;
use super::{broker, control}; use super::{broker, control};
use crate::model::{segment, track}; use crate::model::{segment, track};
pub struct Session<S: SendStream + SendStreamUnframed + Send, B: BidiStream<SendStream = S>, C: Connection<SendStream = S, BidiStream = B> + Send> { pub struct Session<S: SendStream + SendStreamUnframed + Send, C: Connection + Send> {
// Objects are sent to the client // Objects are sent to the client
objects: SendObjects<C>, objects: SendObjects<C>,
@ -23,9 +25,13 @@ pub struct Session<S: SendStream + SendStreamUnframed + Send, B: BidiStream<Send
// A list of tasks that are currently running. // A list of tasks that are currently running.
run_subscribes: JoinSet<SubscribeError>, // run subscriptions, sending the returned error if they fail run_subscribes: JoinSet<SubscribeError>, // run subscriptions, sending the returned error if they fail
_marker: PhantomData<S>,
} }
impl<S: SendStream + SendStreamUnframed + Send, B: BidiStream<SendStream = S>, C: Connection<SendStream = S, BidiStream = B> + Send + 'static> Session<S, B, C> { impl<S, C> Session<S, C> where
S: SendStream + SendStreamUnframed + Send,
C: Connection<SendStream = S> + Send + 'static {
pub fn new( pub fn new(
objects: SendObjects<C>, objects: SendObjects<C>,
control: control::Component<control::Distribute>, control: control::Component<control::Distribute>,
@ -36,6 +42,7 @@ impl<S: SendStream + SendStreamUnframed + Send, B: BidiStream<SendStream = S>, C
control, control,
broker, broker,
run_subscribes: JoinSet::new(), run_subscribes: JoinSet::new(),
_marker: PhantomData,
} }
} }

View File

@ -1,3 +1,5 @@
use std::marker::PhantomData;
use anyhow::Context; use anyhow::Context;
use moq_generic_transport::{SendStream, SendStreamUnframed, BidiStream, Connection, RecvStream}; use moq_generic_transport::{SendStream, SendStreamUnframed, BidiStream, Connection, RecvStream};
@ -6,16 +8,23 @@ use super::{broker, contribute, control, distribute};
use moq_transport::{Role, SetupServer, Version}; use moq_transport::{Role, SetupServer, Version};
use moq_transport_quinn::Connect; use moq_transport_quinn::Connect;
pub struct Session<S: SendStream + SendStreamUnframed + Send, R: RecvStream + Send, B: BidiStream<SendStream = S, RecvStream = R>, C: Connection<SendStream = S, RecvStream = R, BidiStream = B> + Send> { pub struct Session<R: RecvStream + Send, S: SendStream + SendStreamUnframed + Send, C: Connection + Send> {
// Split logic into contribution/distribution to reduce the problem space. // Split logic into contribution/distribution to reduce the problem space.
contribute: contribute::Session<S, R, B, C>, contribute: contribute::Session<R, C>,
distribute: distribute::Session<S, B, C>, distribute: distribute::Session<S, C>,
// Used to receive control messages and forward to contribute/distribute. // Used to receive control messages and forward to contribute/distribute.
control: control::Main<S, B>, control: control::Main<C::BidiStream>,
_marker: PhantomData<S>,
_marker_r: PhantomData<R>,
} }
impl<S: SendStream + SendStreamUnframed + Send + 'static, B: BidiStream<SendStream = S, RecvStream = R>, R: RecvStream + Send + 'static, C: Connection<SendStream = S, RecvStream = R, BidiStream = B> + Send + 'static> Session<S, R, B, C> { // impl<R: RecvStream + Send + 'static, S: SendStream + SendStreamUnframed + Send, C: Connection<RecvStream = R, SendStream = S> + Send + 'static> Session<R, S, C> {
impl<R, S, C> Session<R, S, C> where
R: RecvStream + Send + 'static,
S: SendStream + SendStreamUnframed + Send,
C: Connection<RecvStream = R, SendStream = S> + Send + 'static
{
// pub async fn accept(session: Connect, broker: broker::Broadcasts) -> anyhow::Result<Session<S, R, B, C>> { // pub async fn accept(session: Connect, broker: broker::Broadcasts) -> anyhow::Result<Session<S, R, B, C>> {
// // Accep the WebTransport session. // // Accep the WebTransport session.
// // OPTIONAL validate the conn.uri() otherwise call conn.reject() // // OPTIONAL validate the conn.uri() otherwise call conn.reject()
@ -63,9 +72,9 @@ impl<S: SendStream + SendStreamUnframed + Send + 'static, B: BidiStream<SendStre
// } // }
pub async fn from_session( pub async fn from_session(
session: moq_transport_trait::Session<S, R, B, C>, session: moq_transport_trait::Session<C>,
broker: broker::Broadcasts, broker: broker::Broadcasts,
) -> anyhow::Result<Session<S, R, B, C>> { ) -> anyhow::Result<Session<R, S, C>> {
let (control, objects) = session.split(); let (control, objects) = session.split();
let (objects_send, objects_recv) = objects.split(); let (objects_send, objects_recv) = objects.split();
@ -78,6 +87,8 @@ impl<S: SendStream + SendStreamUnframed + Send + 'static, B: BidiStream<SendStre
control, control,
contribute, contribute,
distribute, distribute,
_marker: PhantomData,
_marker_r: PhantomData,
}; };
Ok(session) Ok(session)