2
2
extern crate log;
3
3
4
4
use anyhow:: { bail, Context , Error , Result } ;
5
+ use async_trait:: async_trait;
5
6
use base64:: Engine ;
7
+ use cmdline:: { AuthSubcommand , Command } ;
6
8
use rand:: { rngs:: OsRng , RngCore } ;
7
9
use sccache:: config:: {
8
10
scheduler as scheduler_config, server as server_config, INSECURE_DIST_CLIENT_TOKEN ,
@@ -22,17 +24,16 @@ use std::env;
22
24
use std:: io;
23
25
use std:: path:: Path ;
24
26
use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
25
- use std:: sync:: { Mutex , MutexGuard } ;
27
+ use std:: sync:: { Arc , Mutex , MutexGuard } ;
26
28
use std:: time:: { Duration , Instant } ;
29
+ use tokio:: runtime:: Runtime ;
27
30
28
31
#[ cfg_attr( target_os = "freebsd" , path = "build_freebsd.rs" ) ]
29
32
mod build;
30
33
31
34
mod cmdline;
32
35
mod token_check;
33
36
34
- use cmdline:: { AuthSubcommand , Command } ;
35
-
36
37
pub const INSECURE_DIST_SERVER_TOKEN : & str = "dangerously_insecure_server" ;
37
38
38
39
// Only supported on x86_64 Linux machines and on FreeBSD
@@ -184,10 +185,10 @@ fn run(command: Command) -> Result<i32> {
184
185
scheduler_config:: ServerAuth :: Insecure => {
185
186
warn ! ( "Scheduler starting with DANGEROUSLY_INSECURE server authentication" ) ;
186
187
let token = INSECURE_DIST_SERVER_TOKEN ;
187
- Box :: new ( move |server_token| check_server_token ( server_token, token) )
188
+ Arc :: new ( move |server_token| check_server_token ( server_token, token) )
188
189
}
189
190
scheduler_config:: ServerAuth :: Token { token } => {
190
- Box :: new ( move |server_token| check_server_token ( server_token, & token) )
191
+ Arc :: new ( move |server_token| check_server_token ( server_token, & token) )
191
192
}
192
193
scheduler_config:: ServerAuth :: JwtHS256 { secret_key } => {
193
194
let secret_key = BASE64_URL_SAFE_ENGINE
@@ -203,7 +204,7 @@ fn run(command: Command) -> Result<i32> {
203
204
validation. validate_nbf = false ;
204
205
validation
205
206
} ;
206
- Box :: new ( move |server_token| {
207
+ Arc :: new ( move |server_token| {
207
208
check_jwt_server_token ( server_token, & secret_key, & validation)
208
209
} )
209
210
}
@@ -217,7 +218,10 @@ fn run(command: Command) -> Result<i32> {
217
218
check_client_auth,
218
219
check_server_auth,
219
220
) ;
220
- http_scheduler. start ( ) ?;
221
+
222
+ // Create runtime after daemonize because Tokio doesn't work well with daemonize
223
+ let runtime = Runtime :: new ( ) . context ( "Failed to create Tokio runtime" ) ?;
224
+ runtime. block_on ( async { http_scheduler. start ( ) . await } ) ?;
221
225
unreachable ! ( ) ;
222
226
}
223
227
@@ -294,7 +298,8 @@ fn run(command: Command) -> Result<i32> {
294
298
server,
295
299
)
296
300
. context ( "Failed to create sccache HTTP server instance" ) ?;
297
- http_server. start ( ) ?;
301
+ let runtime = Runtime :: new ( ) . context ( "Failed to create Tokio runtime" ) ?;
302
+ runtime. block_on ( async { http_server. start ( ) . await } ) ?;
298
303
unreachable ! ( ) ;
299
304
}
300
305
}
@@ -399,8 +404,9 @@ impl Default for Scheduler {
399
404
}
400
405
}
401
406
407
+ #[ async_trait]
402
408
impl SchedulerIncoming for Scheduler {
403
- fn handle_alloc_job (
409
+ async fn handle_alloc_job (
404
410
& self ,
405
411
requester : & dyn SchedulerOutgoing ,
406
412
tc : Toolchain ,
@@ -499,6 +505,7 @@ impl SchedulerIncoming for Scheduler {
499
505
need_toolchain,
500
506
} = requester
501
507
. do_assign_job ( server_id, job_id, tc, auth. clone ( ) )
508
+ . await
502
509
. with_context ( || {
503
510
// LOCKS
504
511
let mut servers = self . servers . lock ( ) . unwrap ( ) ;
@@ -717,7 +724,7 @@ impl SchedulerIncoming for Scheduler {
717
724
pub struct Server {
718
725
builder : Box < dyn BuilderIncoming > ,
719
726
cache : Mutex < TcCache > ,
720
- job_toolchains : Mutex < HashMap < JobId , Toolchain > > ,
727
+ job_toolchains : tokio :: sync :: Mutex < HashMap < JobId , Toolchain > > ,
721
728
}
722
729
723
730
impl Server {
@@ -731,18 +738,19 @@ impl Server {
731
738
Ok ( Server {
732
739
builder,
733
740
cache : Mutex :: new ( cache) ,
734
- job_toolchains : Mutex :: new ( HashMap :: new ( ) ) ,
741
+ job_toolchains : tokio :: sync :: Mutex :: new ( HashMap :: new ( ) ) ,
735
742
} )
736
743
}
737
744
}
738
745
746
+ #[ async_trait]
739
747
impl ServerIncoming for Server {
740
- fn handle_assign_job ( & self , job_id : JobId , tc : Toolchain ) -> Result < AssignJobResult > {
748
+ async fn handle_assign_job ( & self , job_id : JobId , tc : Toolchain ) -> Result < AssignJobResult > {
741
749
let need_toolchain = !self . cache . lock ( ) . unwrap ( ) . contains_toolchain ( & tc) ;
742
750
assert ! ( self
743
751
. job_toolchains
744
752
. lock( )
745
- . unwrap ( )
753
+ . await
746
754
. insert( job_id, tc)
747
755
. is_none( ) ) ;
748
756
let state = if need_toolchain {
@@ -756,18 +764,19 @@ impl ServerIncoming for Server {
756
764
need_toolchain,
757
765
} )
758
766
}
759
- fn handle_submit_toolchain (
767
+ async fn handle_submit_toolchain (
760
768
& self ,
761
769
requester : & dyn ServerOutgoing ,
762
770
job_id : JobId ,
763
- tc_rdr : ToolchainReader ,
771
+ tc_rdr : ToolchainReader < ' _ > ,
764
772
) -> Result < SubmitToolchainResult > {
765
773
requester
766
774
. do_update_job_state ( job_id, JobState :: Ready )
775
+ . await
767
776
. context ( "Updating job state failed" ) ?;
768
777
// TODO: need to lock the toolchain until the container has started
769
778
// TODO: can start prepping container
770
- let tc = match self . job_toolchains . lock ( ) . unwrap ( ) . get ( & job_id) . cloned ( ) {
779
+ let tc = match self . job_toolchains . lock ( ) . await . get ( & job_id) . cloned ( ) {
771
780
Some ( tc) => tc,
772
781
None => return Ok ( SubmitToolchainResult :: JobNotFound ) ,
773
782
} ;
@@ -783,18 +792,19 @@ impl ServerIncoming for Server {
783
792
. map ( |_| SubmitToolchainResult :: Success )
784
793
. unwrap_or ( SubmitToolchainResult :: CannotCache ) )
785
794
}
786
- fn handle_run_job (
795
+ async fn handle_run_job (
787
796
& self ,
788
797
requester : & dyn ServerOutgoing ,
789
798
job_id : JobId ,
790
799
command : CompileCommand ,
791
800
outputs : Vec < String > ,
792
- inputs_rdr : InputsReader ,
801
+ inputs_rdr : InputsReader < ' _ > ,
793
802
) -> Result < RunJobResult > {
794
803
requester
795
804
. do_update_job_state ( job_id, JobState :: Started )
805
+ . await
796
806
. context ( "Updating job state failed" ) ?;
797
- let tc = self . job_toolchains . lock ( ) . unwrap ( ) . remove ( & job_id) ;
807
+ let tc = self . job_toolchains . lock ( ) . await . remove ( & job_id) ;
798
808
let res = match tc {
799
809
None => Ok ( RunJobResult :: JobNotFound ) ,
800
810
Some ( tc) => {
@@ -812,6 +822,7 @@ impl ServerIncoming for Server {
812
822
} ;
813
823
requester
814
824
. do_update_job_state ( job_id, JobState :: Complete )
825
+ . await
815
826
. context ( "Updating job state failed" ) ?;
816
827
res
817
828
}
0 commit comments