@@ -7,8 +7,8 @@ use crate::server::Data;
7
7
use crate :: utils;
8
8
use rusoto_core:: request:: HttpClient ;
9
9
use rusoto_s3:: S3Client ;
10
- use std:: sync:: { mpsc , Arc , Mutex } ;
11
- use std:: thread;
10
+ use std:: sync:: { Arc , Mutex } ;
11
+ use std:: thread:: { self , Thread } ;
12
12
use std:: time:: Duration ;
13
13
14
14
// Automatically wake up the reports generator thread every 10 minutes to check for new jobs
@@ -32,7 +32,7 @@ fn generate_report(data: &Data, ex: &Experiment, results: &DatabaseDB) -> Fallib
32
32
Ok ( res)
33
33
}
34
34
35
- fn reports_thread ( data : & Data , wakes : & mpsc :: Receiver < ( ) > ) -> Fallible < ( ) > {
35
+ fn reports_thread ( data : & Data ) -> Fallible < ( ) > {
36
36
let timeout = Duration :: from_secs ( AUTOMATIC_THREAD_WAKEUP ) ;
37
37
let results = DatabaseDB :: new ( & data. db ) ;
38
38
@@ -41,9 +41,7 @@ fn reports_thread(data: &Data, wakes: &mpsc::Receiver<()>) -> Fallible<()> {
41
41
Some ( ex) => ex,
42
42
None => {
43
43
// This will sleep AUTOMATIC_THREAD_WAKEUP seconds *or* until a wake is received
44
- if let Err ( mpsc:: RecvTimeoutError :: Disconnected ) = wakes. recv_timeout ( timeout) {
45
- thread:: sleep ( timeout) ;
46
- }
44
+ std:: thread:: park_timeout ( timeout) ;
47
45
48
46
continue ;
49
47
}
@@ -128,43 +126,28 @@ fn reports_thread(data: &Data, wakes: &mpsc::Receiver<()>) -> Fallible<()> {
128
126
}
129
127
130
128
#[ derive( Clone , Default ) ]
131
- pub struct ReportsWorker ( Arc < Mutex < Option < mpsc :: Sender < ( ) > > > > ) ;
129
+ pub struct ReportsWorker ( Arc < Mutex < Option < Thread > > > ) ;
132
130
133
131
impl ReportsWorker {
134
132
pub fn new ( ) -> Self {
135
133
ReportsWorker ( Arc :: new ( Mutex :: new ( None ) ) )
136
134
}
137
135
138
136
pub fn spawn ( & self , data : Data ) {
139
- let waker = self . 0 . clone ( ) ;
140
- thread:: spawn ( move || {
141
- // Set up a new waker channel
142
- let ( wake_send, wake_recv) = mpsc:: channel ( ) ;
143
- {
144
- let mut waker = waker. lock ( ) . unwrap ( ) ;
145
- * waker = Some ( wake_send) ;
146
- }
147
-
148
- loop {
149
- let result = reports_thread ( & data. clone ( ) , & wake_recv)
150
- . with_context ( |_| "the reports generator thread crashed" ) ;
151
- if let Err ( e) = result {
152
- utils:: report_failure ( & e) ;
153
- }
154
-
155
- warn ! ( "the reports generator thread will be respawned in one minute" ) ;
156
- thread:: sleep ( Duration :: from_secs ( 60 ) ) ;
137
+ let joiner = thread:: spawn ( move || loop {
138
+ let result = reports_thread ( & data. clone ( ) )
139
+ . with_context ( |_| "the reports generator thread crashed" ) ;
140
+ if let Err ( e) = result {
141
+ utils:: report_failure ( & e) ;
157
142
}
158
143
} ) ;
144
+ * self . 0 . lock ( ) . unwrap_or_else ( |e| e. into_inner ( ) ) = Some ( joiner. thread ( ) . clone ( ) ) ;
159
145
}
160
146
161
147
pub fn wake ( & self ) {
162
- // We don't really care if the wake fails: the reports generator thread wakes up on its own
163
- // every few minutes, so this just speeds up the process
164
- if let Some ( waker) = self . 0 . lock ( ) . ok ( ) . as_ref ( ) . and_then ( |opt| opt. as_ref ( ) ) {
165
- if waker. send ( ( ) ) . is_err ( ) {
166
- warn ! ( "can't wake the reports generator, will have to wait" ) ;
167
- }
148
+ let guard = self . 0 . lock ( ) . unwrap_or_else ( |e| e. into_inner ( ) ) ;
149
+ if let Some ( thread) = & * guard {
150
+ thread. unpark ( ) ;
168
151
} else {
169
152
warn ! ( "no report generator to wake up!" ) ;
170
153
}
0 commit comments