@ -33,7 +33,7 @@ use std::{
pin ::Pin ,
result ,
sync ::{ Arc , RwLock } ,
time ::Duration ,
time ::{ Duration , Instant } ,
} ;
use futures ::{
@ -174,6 +174,7 @@ pub enum IsOnline {
Err {
value : Error ,
retries : u64 ,
wait : Option < ( Instant , Duration ) > ,
} ,
}
@ -189,9 +190,19 @@ impl IsOnline {
* self = Self ::Err {
value : err ,
retries : 1 ,
wait : None ,
} ;
}
}
pub fn wait_left ( & self ) -> Option < Duration > {
if let Self ::Err { ref wait , .. } = self {
let wait = wait . as_ref ( ) ? ;
Some ( wait . 1. saturating_sub ( Instant ::now ( ) - wait . 0 ) )
} else {
None
}
}
}
#[ derive(Debug) ]
@ -210,7 +221,7 @@ pub struct Account {
pub main_loop_handler : MainLoopHandler ,
pub active_jobs : HashMap < JobId , JobRequest > ,
pub active_job_instants : BTreeMap < std::time :: Instant, JobId > ,
pub active_job_instants : BTreeMap < Instant, JobId > ,
pub event_queue : VecDeque < ( MailboxHash , RefreshEvent ) > ,
pub backend_capabilities : MailBackendCapabilities ,
}
@ -526,7 +537,7 @@ impl Account {
} ;
let job_id = handle . job_id ;
active_jobs . insert ( job_id , JobRequest ::Mailboxes { handle } ) ;
active_job_instants . insert ( std::time :: Instant::now ( ) , job_id ) ;
active_job_instants . insert ( Instant::now ( ) , job_id ) ;
main_loop_handler . send ( ThreadEvent ::UIEvent ( UIEvent ::StatusEvent (
StatusEvent ::NewJob ( job_id ) ,
) ) ) ;
@ -737,8 +748,7 @@ impl Account {
handle ,
} ,
) ;
self . active_job_instants
. insert ( std ::time ::Instant ::now ( ) , job_id ) ;
self . active_job_instants . insert ( Instant ::now ( ) , job_id ) ;
}
}
} ) ;
@ -1640,6 +1650,7 @@ impl Account {
IsOnline ::Err {
value ,
ref mut retries ,
ref mut wait ,
} = > {
let ret = Err ( value . clone ( ) ) ;
if value . kind . is_authentication ( )
@ -1655,52 +1666,41 @@ impl Account {
{
return ret ;
}
let wait = if value . kind . is_timeout ( )
let new_ wait = if value . kind . is_timeout ( )
| | value . kind . is_network_down ( )
| | value . kind . is_oserror ( )
{
let oldval = * retries ;
if oldval ! = 8 {
if oldval ! = 4 {
* retries * = 2 ;
}
Some ( Duration ::from_millis (
oldval * ( 4 * melib ::utils ::random ::random_u8 ( ) as u64 ) ,
) )
} else {
Some ( Duration ::from_secs ( 5 * 60 ) )
}
} else {
None
} ;
* wait = new_wait . map ( | dur | ( Instant ::now ( ) , dur ) ) ;
( ret , wait)
( ret , new_ wait)
}
} ;
if ! self . active_jobs . values ( ) . any ( JobRequest ::is_online ) {
let online_fut = self . backend . read ( ) . unwrap ( ) . is_online ( ) ;
if let Ok ( online_fut ) = online_fut {
use melib ::utils ::futures ::sleep ;
let handle = match ( wait , self . backend_capabilities . is_async ) {
( Some ( wait ) , true ) = > self . main_loop_handler . job_executor . spawn_specialized (
"is_online" . into ( ) ,
async move {
sleep ( wait ) . await ;
online_fut . await
} ,
) ,
( None , true ) = > self
. main_loop_handler
let handle = if self . backend_capabilities . is_async {
self . main_loop_handler
. job_executor
. spawn_specialized ( "is_online" . into ( ) , online_fut ) ,
( Some ( wait ) , false ) = > self . main_loop_handler . job_executor . spawn_blocking (
. spawn_specialized_delayed ( "is_online" . into ( ) , online_fut , wait )
} else {
self . main_loop_handler . job_executor . spawn_blocking_delayed (
"is_online" . into ( ) ,
async move {
sleep ( wait ) . await ;
online_fut . await
} ,
) ,
( None , false ) = > self
. main_loop_handler
. job_executor
. spawn_blocking ( "is_online" . into ( ) , online_fut ) ,
online_fut ,
wait ,
)
} ;
self . insert_job ( handle . job_id , JobRequest ::IsOnline { handle } ) ;
}
@ -1908,23 +1908,15 @@ impl Account {
return true ;
}
Err ( value ) = > {
self . is_online = IsOnline ::Err { value , retries : 1 } ;
self . is_online = IsOnline ::Err {
value ,
retries : 1 ,
wait : None ,
} ;
}
}
}
let online_job = self . backend . read ( ) . unwrap ( ) . is_online ( ) ;
if let Ok ( online_job ) = online_job {
let handle = if self . backend_capabilities . is_async {
self . main_loop_handler
. job_executor
. spawn_specialized ( "is_online" . into ( ) , online_job )
} else {
self . main_loop_handler
. job_executor
. spawn_blocking ( "is_online" . into ( ) , online_job )
} ;
self . insert_job ( handle . job_id , JobRequest ::IsOnline { handle } ) ;
} ;
_ = self . is_online ( ) ;
}
JobRequest ::Refresh { ref mut handle , .. } = > {
match handle . chan . try_recv ( ) {
@ -2333,8 +2325,7 @@ impl Account {
pub fn insert_job ( & mut self , job_id : JobId , job : JobRequest ) {
self . active_jobs . insert ( job_id , job ) ;
self . active_job_instants
. insert ( std ::time ::Instant ::now ( ) , job_id ) ;
self . active_job_instants . insert ( Instant ::now ( ) , job_id ) ;
self . main_loop_handler
. send ( ThreadEvent ::UIEvent ( UIEvent ::StatusEvent (
StatusEvent ::NewJob ( job_id ) ,