@@ -12,7 +12,7 @@ use std::{collections::BTreeMap, time::Duration};
1212
1313use openmina_core:: bug_condition;
1414use serde:: Serialize ;
15- use tokio:: sync:: Mutex ;
15+ use tokio:: sync:: Semaphore ;
1616
1717#[ cfg( not( target_arch = "wasm32" ) ) ]
1818use tokio:: task:: spawn_local;
@@ -226,7 +226,12 @@ async fn wait_for_ice_gathering_complete(pc: &mut RTCConnection) {
226226 }
227227}
228228
229- async fn peer_start ( api : Api , args : PeerAddArgs , abort : broadcast:: Receiver < ( ) > ) {
229+ async fn peer_start (
230+ api : Api ,
231+ args : PeerAddArgs ,
232+ abort : broadcast:: Receiver < ( ) > ,
233+ closed : broadcast:: Sender < ( ) > ,
234+ ) {
230235 let PeerAddArgs {
231236 peer_id,
232237 kind,
@@ -337,7 +342,6 @@ async fn peer_start(api: Api, args: PeerAddArgs, abort: broadcast::Receiver<()>)
337342 connected_tx. send ( Ok ( ( ) ) ) . unwrap ( ) ;
338343 } else {
339344 let mut connected_tx = Some ( connected_tx) ;
340- let event_sender = event_sender. clone ( ) ;
341345 pc. on_connection_state_change ( Box :: new ( move |state| {
342346 match state {
343347 RTCConnectionState :: Connected => {
@@ -349,7 +353,7 @@ async fn peer_start(api: Api, args: PeerAddArgs, abort: broadcast::Receiver<()>)
349353 if let Some ( connected_tx) = connected_tx. take ( ) {
350354 let _ = connected_tx. send ( Err ( "disconnected" ) ) ;
351355 } else {
352- let _ = event_sender ( P2pConnectionEvent :: Closed ( peer_id ) . into ( ) ) ;
356+ let _ = closed . send ( ( ) ) ;
353357 }
354358 }
355359 _ => { }
@@ -365,6 +369,7 @@ async fn peer_start(api: Api, args: PeerAddArgs, abort: broadcast::Receiver<()>)
365369 Ok ( _) => { }
366370 Err ( err) => {
367371 let _ = event_sender ( P2pConnectionEvent :: Finalized ( peer_id, Err ( err) ) . into ( ) ) ;
372+ return ;
368373 }
369374 }
370375
@@ -727,50 +732,45 @@ pub trait P2pServiceWebrtc: redux::Service {
727732 fn peers ( & mut self ) -> & mut BTreeMap < PeerId , PeerState > ;
728733
729734 fn init < S : TaskSpawner > ( secret_key : SecretKey , spawner : S ) -> P2pServiceCtx {
735+ const MAX_PEERS : usize = 500 ;
730736 let ( cmd_sender, mut cmd_receiver) = mpsc:: unbounded_channel ( ) ;
731737
732738 let _ = secret_key;
733739
734740 spawner. spawn_main ( "webrtc" , async move {
735741 #[ allow( clippy:: all) ]
736742 let api = build_api ( ) ;
737- let active_peers = Arc :: new ( Mutex :: new ( BTreeMap :: new ( ) ) ) ;
743+ let conn_permits = Arc :: new ( Semaphore :: const_new ( MAX_PEERS ) ) ;
738744 while let Some ( cmd) = cmd_receiver. recv ( ) . await {
739745 match cmd {
740- Cmd :: PeerAdd { args, abort } => {
746+ Cmd :: PeerAdd { args, mut abort } => {
741747 #[ allow( clippy:: all) ]
742748 let api = api. clone ( ) ;
743- let active_peers = active_peers. clone ( ) ;
749+ let conn_permits = conn_permits. clone ( ) ;
750+ let peer_id = args. peer_id ;
751+ let event_sender = args. event_sender . clone ( ) ;
744752 spawn_local ( async move {
745- let peer_id = args. peer_id ;
746- let ( abort_finished_tx, abort_finished) = broadcast:: channel :: < ( ) > ( 1 ) ;
747- let mut aborted = abort. resubscribe ( ) ;
748-
749- if let Some ( mut abort_finished) =
750- active_peers. lock ( ) . await . insert ( peer_id, abort_finished)
751- {
752- // wait for peer conn with same id to finish.
753- let _ = abort_finished. recv ( ) . await ;
754- }
755- if active_peers. lock ( ) . await . len ( ) > 100 {
756- sleep ( Duration :: from_millis ( 500 ) ) . await ;
757- }
758-
753+ let Ok ( _permit) = conn_permits. try_acquire ( ) else {
754+ // state machine shouldn't allow this to happen.
755+ bug_condition ! ( "P2P WebRTC Semaphore acquisition failed!" ) ;
756+ return ;
757+ } ;
758+ let ( closed_tx, mut closed) = broadcast:: channel ( 1 ) ;
759+ let event_sender_clone = event_sender. clone ( ) ;
760+ spawn_local ( async move {
761+ // to avoid sending closed multiple times
762+ let _ = closed. recv ( ) . await ;
763+ event_sender_clone ( P2pConnectionEvent :: Closed ( peer_id) . into ( ) ) ;
764+ } ) ;
759765 tokio:: select! {
760- _ = aborted. recv( ) => { }
761- _ = peer_start( api, args, abort) => { }
766+ _ = peer_start( api, args, abort. resubscribe( ) , closed_tx. clone( ) ) => { }
767+ _ = abort. recv( ) => {
768+ }
762769 }
763770
764- // delay removing active_peer to give some time for cleanup.
765- sleep ( Duration :: from_millis ( 500 ) ) . await ;
766- let rx1 = abort_finished_tx. subscribe ( ) ;
767- let mut active_peers = active_peers. lock ( ) . await ;
768- if let Some ( rx) = active_peers
769- . remove ( & peer_id)
770- . filter ( |rx2| !rx2. same_channel ( & rx1) )
771- {
772- active_peers. insert ( peer_id, rx) ;
773- }
771+ // delay dropping permit to give some time for cleanup.
772+ sleep ( Duration :: from_millis ( 100 ) ) . await ;
773+ let _ = closed_tx. send ( ( ) ) ;
774774 } ) ;
775775 }
776776 }
0 commit comments