@@ -1568,6 +1568,9 @@ fn get_setup() -> Setup {
15681568#[ tokio:: main( flavor = "current_thread" ) ]
15691569async fn main ( ) {
15701570 const RUST_BACKTRACE : & str = "RUST_BACKTRACE" ;
1571+ const RECONNECT_RATE_LIMIT_WINDOW : Duration = Duration :: from_secs ( 600 ) ;
1572+ const RECONNECT_RATE_LIMIT : usize = 5 ;
1573+
15711574 if env:: var ( RUST_BACKTRACE ) . is_err ( ) {
15721575 env:: set_var ( RUST_BACKTRACE , "full" )
15731576 }
@@ -1585,14 +1588,18 @@ async fn main() {
15851588 if setup. enable_discovery {
15861589 let device_id = setup. session_config . device_id . clone ( ) ;
15871590
1588- discovery = Some (
1589- librespot:: discovery:: Discovery :: builder ( device_id)
1590- . name ( setup. connect_config . name . clone ( ) )
1591- . device_type ( setup. connect_config . device_type )
1592- . port ( setup. zeroconf_port )
1593- . launch ( )
1594- . unwrap ( ) ,
1595- ) ;
1591+ discovery = match librespot:: discovery:: Discovery :: builder ( device_id)
1592+ . name ( setup. connect_config . name . clone ( ) )
1593+ . device_type ( setup. connect_config . device_type )
1594+ . port ( setup. zeroconf_port )
1595+ . launch ( )
1596+ {
1597+ Ok ( d) => Some ( d) ,
1598+ Err ( e) => {
1599+ error ! ( "Discovery Error: {}" , e) ;
1600+ exit ( 1 ) ;
1601+ }
1602+ }
15961603 }
15971604
15981605 if let Some ( credentials) = setup. credentials {
@@ -1609,7 +1616,12 @@ async fn main() {
16091616
16101617 loop {
16111618 tokio:: select! {
1612- credentials = async { discovery. as_mut( ) . unwrap( ) . next( ) . await } , if discovery. is_some( ) => {
1619+ credentials = async {
1620+ match discovery. as_mut( ) {
1621+ Some ( d) => d. next( ) . await ,
1622+ _ => None
1623+ }
1624+ } , if discovery. is_some( ) => {
16131625 match credentials {
16141626 Some ( credentials) => {
16151627 last_credentials = Some ( credentials. clone( ) ) ;
@@ -1630,8 +1642,8 @@ async fn main() {
16301642 ) . fuse( ) ) ;
16311643 } ,
16321644 None => {
1633- warn !( "Discovery stopped! " ) ;
1634- discovery = None ;
1645+ error !( "Discovery stopped unexpectedly " ) ;
1646+ exit ( 1 ) ;
16351647 }
16361648 }
16371649 } ,
@@ -1682,40 +1694,48 @@ async fn main() {
16821694 exit( 1 ) ;
16831695 }
16841696 } ,
1685- _ = async { spirc_task. as_mut( ) . unwrap( ) . await } , if spirc_task. is_some( ) => {
1697+ _ = async {
1698+ if let Some ( task) = spirc_task. as_mut( ) {
1699+ task. await ;
1700+ }
1701+ } , if spirc_task. is_some( ) => {
16861702 spirc_task = None ;
16871703
16881704 warn!( "Spirc shut down unexpectedly" ) ;
1689- while !auto_connect_times. is_empty( )
1690- && ( ( Instant :: now( ) - auto_connect_times[ 0 ] ) . as_secs( ) > 600 )
1691- {
1692- let _ = auto_connect_times. remove( 0 ) ;
1693- }
16941705
1695- if let Some ( credentials) = last_credentials. clone( ) {
1696- if auto_connect_times. len( ) >= 5 {
1697- warn!( "Spirc shut down too often. Not reconnecting automatically." ) ;
1698- } else {
1706+ let mut reconnect_exceeds_rate_limit = || {
1707+ auto_connect_times. retain( |& t| t. elapsed( ) < RECONNECT_RATE_LIMIT_WINDOW ) ;
1708+ auto_connect_times. len( ) > RECONNECT_RATE_LIMIT
1709+ } ;
1710+
1711+ match last_credentials. clone( ) {
1712+ Some ( credentials) if !reconnect_exceeds_rate_limit( ) => {
16991713 auto_connect_times. push( Instant :: now( ) ) ;
17001714
17011715 connecting = Box :: pin( Session :: connect(
17021716 setup. session_config. clone( ) ,
17031717 credentials,
17041718 setup. cache. clone( ) ,
17051719 ) . fuse( ) ) ;
1706- }
1720+ } ,
1721+ _ => {
1722+ error!( "Spirc shut down too often. Not reconnecting automatically." ) ;
1723+ exit( 1 ) ;
1724+ } ,
17071725 }
17081726 } ,
1709- event = async { player_event_channel. as_mut( ) . unwrap( ) . recv( ) . await } , if player_event_channel. is_some( ) => match event {
1727+ event = async {
1728+ match player_event_channel. as_mut( ) {
1729+ Some ( p) => p. recv( ) . await ,
1730+ _ => None
1731+ }
1732+ } , if player_event_channel. is_some( ) => match event {
17101733 Some ( event) => {
17111734 if let Some ( program) = & setup. player_event_program {
17121735 if let Some ( child) = run_program_on_events( event, program) {
1713- if child. is_ok( ) {
1714-
1715- let mut child = child. unwrap( ) ;
1716-
1736+ if let Ok ( mut child) = child {
17171737 tokio:: spawn( async move {
1718- match child. wait( ) . await {
1738+ match child. wait( ) . await {
17191739 Ok ( e) if e. success( ) => ( ) ,
17201740 Ok ( e) => {
17211741 if let Some ( code) = e. code( ) {
@@ -1741,7 +1761,8 @@ async fn main() {
17411761 } ,
17421762 _ = tokio:: signal:: ctrl_c( ) => {
17431763 break ;
1744- }
1764+ } ,
1765+ else => break ,
17451766 }
17461767 }
17471768
@@ -1754,7 +1775,8 @@ async fn main() {
17541775 if let Some ( mut spirc_task) = spirc_task {
17551776 tokio:: select! {
17561777 _ = tokio:: signal:: ctrl_c( ) => ( ) ,
1757- _ = spirc_task. as_mut( ) => ( )
1778+ _ = spirc_task. as_mut( ) => ( ) ,
1779+ else => ( ) ,
17581780 }
17591781 }
17601782 }
0 commit comments