1
1
use experiments:: { Experiment , Status } ;
2
2
use prelude:: * ;
3
3
use report;
4
+ use report:: { Comparison , TestResults } ;
4
5
use results:: DatabaseDB ;
5
6
use rusoto_core:: request:: HttpClient ;
6
7
use rusoto_s3:: S3Client ;
@@ -10,7 +11,6 @@ use std::sync::{mpsc, Arc, Mutex};
10
11
use std:: thread;
11
12
use std:: time:: Duration ;
12
13
use utils;
13
- use report:: { Comparison , TestResults } ;
14
14
15
15
// Automatically wake up the reports generator thread every 10 minutes to check for new jobs
16
16
const AUTOMATIC_THREAD_WAKEUP : u64 = 600 ;
@@ -20,7 +20,7 @@ fn generate_report(data: &Data, ex: &Experiment, results: &DatabaseDB) -> Fallib
20
20
HttpClient :: new ( ) ?,
21
21
data. tokens . reports_bucket . to_aws_credentials ( ) ,
22
22
data. tokens . reports_bucket . region . to_region ( ) ?,
23
- ) ;
23
+ ) ;
24
24
let dest = format ! ( "s3://{}/{}" , data. tokens. reports_bucket. bucket, & ex. name) ;
25
25
let writer = report:: S3Writer :: create ( Box :: new ( client) , dest. parse ( ) ?) ?;
26
26
@@ -37,130 +37,131 @@ fn reports_thread(data: &Data, wakes: &mpsc::Receiver<()>) -> Fallible<()> {
37
37
let mut ex = match Experiment :: first_by_status ( & data. db , Status :: NeedsReport ) ? {
38
38
Some ( ex) => ex,
39
39
None => {
40
- // This will sleep AUTOMATIC_THREAD_WAKEUP seconds *or* until a wake is received
41
- if let Err ( mpsc:: RecvTimeoutError :: Disconnected ) = wakes. recv_timeout ( timeout) {
42
- thread:: sleep ( timeout) ;
40
+ // This will sleep AUTOMATIC_THREAD_WAKEUP seconds *or* until a wake is received
41
+ if let Err ( mpsc:: RecvTimeoutError :: Disconnected ) = wakes. recv_timeout ( timeout) {
42
+ thread:: sleep ( timeout) ;
43
+ }
44
+
45
+ continue ;
43
46
}
47
+ } ;
48
+ let name = ex. name . clone ( ) ;
44
49
45
- continue ;
46
- }
47
- } ;
48
- let name = ex. name . clone ( ) ;
49
-
50
- info ! ( "generating report for experiment {}..." , name) ;
51
- ex. set_status ( & data. db , Status :: GeneratingReport ) ?;
52
-
53
- match generate_report ( data, & ex, & results) {
54
- Err ( err) => {
55
- ex. set_status ( & data. db , Status :: ReportFailed ) ?;
56
- error ! ( "failed to generate the report of {}" , name) ;
57
- utils:: report_failure ( & err) ;
58
-
59
- if let Some ( ref github_issue) = ex. github_issue {
60
- Message :: new ( )
61
- . line (
62
- "rotating_light" ,
63
- format ! ( "Report generation of **`{}`** failed: {}" , name, err) ,
64
- ) . line (
65
- "hammer_and_wrench" ,
66
- "If the error is fixed use the `retry-report` command." ,
67
- ) . note (
68
- "sos" ,
69
- "Can someone from the infra team check in on this? @rust-lang/infra" ,
70
- ) . send ( & github_issue. api_url , data) ?;
50
+ info ! ( "generating report for experiment {}..." , name) ;
51
+ ex. set_status ( & data. db , Status :: GeneratingReport ) ?;
52
+
53
+ match generate_report ( data, & ex, & results) {
54
+ Err ( err) => {
55
+ ex. set_status ( & data. db , Status :: ReportFailed ) ?;
56
+ error ! ( "failed to generate the report of {}" , name) ;
57
+ utils:: report_failure ( & err) ;
58
+
59
+ if let Some ( ref github_issue) = ex. github_issue {
60
+ Message :: new ( )
61
+ . line (
62
+ "rotating_light" ,
63
+ format ! ( "Report generation of **`{}`** failed: {}" , name, err) ,
64
+ ) . line (
65
+ "hammer_and_wrench" ,
66
+ "If the error is fixed use the `retry-report` command." ,
67
+ ) . note (
68
+ "sos" ,
69
+ "Can someone from the infra team check in on this? @rust-lang/infra" ,
70
+ ) . send ( & github_issue. api_url , data) ?;
71
71
}
72
72
73
73
continue ;
74
- } ,
75
- Ok ( res) => {
76
-
74
+ }
75
+ Ok ( res) => {
77
76
let base_url = data
78
- . tokens
79
- . reports_bucket
80
- . public_url
81
- . replace ( "{bucket}" , & data. tokens . reports_bucket . bucket ) ;
77
+ . tokens
78
+ . reports_bucket
79
+ . public_url
80
+ . replace ( "{bucket}" , & data. tokens . reports_bucket . bucket ) ;
82
81
let report_url = format ! ( "{}/{}/index.html" , base_url, name) ;
83
82
84
83
ex. set_status ( & data. db , Status :: Completed ) ?;
85
84
ex. set_report_url ( & data. db , & report_url) ?;
86
85
info ! ( "report for the experiment {} generated successfully!" , name) ;
87
86
88
- let ( mut regressed, mut fixed, mut skipped , mut error ) = ( 0 , 0 , 0 , 0 ) ;
89
- res. crates . iter ( ) . for_each ( |krate|
87
+ let ( mut regressed, mut fixed) = ( 0 , 0 ) ;
88
+ res. crates . iter ( ) . for_each ( |krate| {
90
89
match krate. res {
91
- Comparison :: Regressed => regressed = regressed + 1 ,
92
- Comparison :: Fixed => fixed = fixed + 1 ,
93
- Comparison :: Skipped => skipped = skipped + 1 ,
94
- Comparison :: Error => error = error +1 ,
95
- _ => ( ) ,
96
- }
97
- ) ;
98
-
90
+ Comparison :: Regressed => regressed += 1 ,
91
+ Comparison :: Fixed => fixed += 1 ,
92
+ _ => ( ) ,
93
+ } ;
94
+ } ) ;
99
95
100
96
if let Some ( ref github_issue) = ex. github_issue {
101
97
Message :: new ( )
102
- . line ( "tada" , format ! ( "Experiment **`{}`** is completed!" , name) )
103
- . line (
104
- "newspaper" ,
105
- format ! ( "[Open the full report]({})." , report_url) ,
98
+ . line ( "tada" , format ! ( "Experiment **`{}`** is completed!" , name) )
99
+ . line (
100
+ "bar_chart" ,
101
+ format ! (
102
+ " {} regressed and {} fixed ({} total)" ,
103
+ regressed,
104
+ fixed,
105
+ res. crates. len( ) ,
106
+ ) ,
106
107
) . line (
107
- "hash ",
108
- format ! ( " {} | :arrow_left: {} | :white_check_mark: {} | :fast_forward: {} | :x: {} " , res . crates . len ( ) , regressed , fixed , skipped , error ) ,
108
+ "newspaper ",
109
+ format ! ( "[Open the full report]({}). " , report_url ) ,
109
110
) . note (
110
- "warning" ,
111
- format ! (
112
- "If you notice any spurious failure [please add them to the \
113
- blacklist]({}/blob/master/config.toml)!",
114
- :: CRATER_REPO_URL ,
111
+ "warning" ,
112
+ format ! (
113
+ "If you notice any spurious failure [please add them to the \
114
+ blacklist]({}/blob/master/config.toml)!",
115
+ :: CRATER_REPO_URL ,
115
116
) ,
116
117
) . set_label ( Label :: ExperimentCompleted )
117
118
. send ( & github_issue. api_url , data) ?;
118
- }
119
119
}
120
120
}
121
121
}
122
122
}
123
+ }
123
124
124
- #[ derive( Clone , Default ) ]
125
- pub struct ReportsWorker ( Arc < Mutex < Option < mpsc:: Sender < ( ) > > > > ) ;
126
-
127
- impl ReportsWorker {
128
- pub fn new ( ) -> Self {
129
- ReportsWorker ( Arc :: new ( Mutex :: new ( None ) ) )
130
- }
125
+ #[ derive( Clone , Default ) ]
126
+ pub struct ReportsWorker ( Arc < Mutex < Option < mpsc:: Sender < ( ) > > > > ) ;
131
127
132
- pub fn spawn ( & self , data : Data ) {
133
- let waker = self . 0 . clone ( ) ;
134
- thread:: spawn ( move || {
135
- // Set up a new waker channel
136
- let ( wake_send, wake_recv) = mpsc:: channel ( ) ;
137
- {
138
- let mut waker = waker. lock ( ) . unwrap ( ) ;
139
- * waker = Some ( wake_send) ;
140
- }
128
+ impl ReportsWorker {
129
+ pub fn new ( ) -> Self {
130
+ ReportsWorker ( Arc :: new ( Mutex :: new ( None ) ) )
131
+ }
141
132
142
- loop {
143
- let result = reports_thread ( & data. clone ( ) , & wake_recv)
144
- . with_context ( |_| "the reports generator thread crashed" ) ;
145
- if let Err ( e) = result {
146
- utils:: report_failure ( & e) ;
133
+ pub fn spawn ( & self , data : Data ) {
134
+ let waker = self . 0 . clone ( ) ;
135
+ thread:: spawn ( move || {
136
+ // Set up a new waker channel
137
+ let ( wake_send, wake_recv) = mpsc:: channel ( ) ;
138
+ {
139
+ let mut waker = waker. lock ( ) . unwrap ( ) ;
140
+ * waker = Some ( wake_send) ;
147
141
}
148
142
149
- warn ! ( "the reports generator thread will be respawned in one minute" ) ;
150
- thread:: sleep ( Duration :: from_secs ( 60 ) ) ;
151
- }
152
- } ) ;
153
- }
143
+ loop {
144
+ let result = reports_thread ( & data. clone ( ) , & wake_recv)
145
+ . with_context ( |_| "the reports generator thread crashed" ) ;
146
+ if let Err ( e) = result {
147
+ utils:: report_failure ( & e) ;
148
+ }
154
149
155
- pub fn wake ( & self ) {
156
- // We don't really care if the wake fails: the reports generator thread wakes up on its own
157
- // every few minutes, so this just speeds up the process
158
- if let Some ( waker) = self . 0 . lock ( ) . ok ( ) . as_ref ( ) . and_then ( |opt| opt. as_ref ( ) ) {
159
- if waker. send ( ( ) ) . is_err ( ) {
160
- warn ! ( "can't wake the reports generator, will have to wait" ) ;
150
+ warn ! ( "the reports generator thread will be respawned in one minute" ) ;
151
+ thread:: sleep ( Duration :: from_secs ( 60 ) ) ;
152
+ }
153
+ } ) ;
154
+ }
155
+
156
+ pub fn wake ( & self ) {
157
+ // We don't really care if the wake fails: the reports generator thread wakes up on its own
158
+ // every few minutes, so this just speeds up the process
159
+ if let Some ( waker) = self . 0 . lock ( ) . ok ( ) . as_ref ( ) . and_then ( |opt| opt. as_ref ( ) ) {
160
+ if waker. send ( ( ) ) . is_err ( ) {
161
+ warn ! ( "can't wake the reports generator, will have to wait" ) ;
162
+ }
163
+ } else {
164
+ warn ! ( "no report generator to wake up!" ) ;
161
165
}
162
- } else {
163
- warn ! ( "no report generator to wake up!" ) ;
164
166
}
165
167
}
166
- }
0 commit comments