@@ -26,7 +26,7 @@ use crate::{
26
26
CoordinatorMessage , JobId , Multiplexed , OneToOneResponse , ReadFileRequest ,
27
27
ReadFileResponse , SerializedError , WorkerMessage , WriteFileRequest ,
28
28
} ,
29
- sandbox:: { CompileRequest , CompileResponse , CompileResponseWithOutput } ,
29
+ sandbox:: { CompileRequest , CompileResponse , CompileResponseWithOutput , Channel } ,
30
30
DropErrorDetailsExt ,
31
31
} ;
32
32
@@ -38,12 +38,99 @@ enum DemultiplexCommand {
38
38
39
39
#[ derive( Debug ) ]
40
40
pub struct Container {
41
- task : JoinHandle < Result < ( ) > > ,
42
- commander : Commander ,
41
+ stable : ContainerCore ,
42
+ beta : ContainerCore ,
43
+ nightly : ContainerCore ,
43
44
token : CancellationToken ,
44
45
}
45
46
46
47
impl Container {
48
+ pub async fn compile (
49
+ & self ,
50
+ request : CompileRequest ,
51
+ ) -> Result < CompileResponseWithOutput , CompileError > {
52
+ self . select_channel ( request. channel ) . compile ( request) . await
53
+ }
54
+
55
+ pub async fn begin_compile (
56
+ & self ,
57
+ request : CompileRequest ,
58
+ ) -> Result < ActiveCompilation , CompileError > {
59
+ self . select_channel ( request. channel ) . begin_compile ( request) . await
60
+ }
61
+
62
+ pub async fn shutdown ( self ) -> Result < ( ) > {
63
+ let Self {
64
+ stable,
65
+ beta,
66
+ nightly,
67
+ token,
68
+ } = self ;
69
+ token. cancel ( ) ;
70
+
71
+ let ( stable, beta, nightly) = join ! ( stable. shutdown( ) , beta. shutdown( ) , nightly. shutdown( ) ) ;
72
+
73
+ stable. unwrap ( ) ;
74
+ beta. unwrap ( ) ;
75
+ nightly. unwrap ( ) ;
76
+
77
+ Ok ( ( ) )
78
+ // task.await.context(ContainerTaskPanickedSnafu)?
79
+ }
80
+
81
+
82
+ fn select_channel ( & self , channel : Channel ) -> & ContainerCore {
83
+ match channel {
84
+ Channel :: Stable => & self . stable ,
85
+ Channel :: Beta => & self . beta ,
86
+ Channel :: Nightly => & self . nightly ,
87
+ }
88
+ }
89
+ }
90
+
91
+ #[ derive( Debug ) ]
92
+ pub struct ContainerCore {
93
+ task : JoinHandle < Result < ( ) > > ,
94
+ commander : Commander ,
95
+ }
96
+
97
+ impl ContainerCore {
98
+ fn new ( channel : Channel , token : CancellationToken , backend : & impl Backend ) -> Result < Self > {
99
+ let ( mut child, stdin, stdout) = backend. run_worker_in_background ( channel) ?;
100
+ let IoQueue {
101
+ mut tasks,
102
+ to_worker_tx,
103
+ from_worker_rx,
104
+ } = spawn_io_queue ( stdin, stdout, token) ;
105
+
106
+ let ( command_tx, command_rx) = mpsc:: channel ( 8 ) ;
107
+ let demultiplex_task = tokio:: spawn ( Commander :: demultiplex ( command_rx, from_worker_rx) ) ;
108
+
109
+ let task = tokio:: spawn ( async move {
110
+ let ( c, d, t) = join ! ( child. wait( ) , demultiplex_task, tasks. join_next( ) ) ;
111
+ c. context ( JoinWorkerSnafu ) ?;
112
+ d. context ( DemultiplexerTaskPanickedSnafu ) ?
113
+ . context ( DemultiplexerTaskFailedSnafu ) ?;
114
+ if let Some ( t) = t {
115
+ t. context ( IoQueuePanickedSnafu ) ??;
116
+ }
117
+
118
+ Ok ( ( ) )
119
+ } ) ;
120
+
121
+ let commander = Commander {
122
+ to_worker_tx,
123
+ to_demultiplexer_tx : command_tx,
124
+ id : Default :: default ( ) ,
125
+ } ;
126
+
127
+ Ok ( ContainerCore {
128
+ task,
129
+ commander,
130
+ } )
131
+
132
+ }
133
+
47
134
pub async fn compile (
48
135
& self ,
49
136
request : CompileRequest ,
@@ -150,10 +237,8 @@ impl Container {
150
237
let Self {
151
238
task,
152
239
commander,
153
- token,
154
240
} = self ;
155
241
drop ( commander) ;
156
- token. cancel ( ) ;
157
242
task. await . context ( ContainerTaskPanickedSnafu ) ?
158
243
}
159
244
}
@@ -423,37 +508,14 @@ impl<B: Backend> Coordinator<B> {
423
508
pub fn allocate ( & mut self ) -> Result < Container , Error > {
424
509
let token = CancellationToken :: new ( ) ;
425
510
426
- let ( mut child, stdin, stdout) = self . backend . run_worker_in_background ( ) ?;
427
- let IoQueue {
428
- mut tasks,
429
- to_worker_tx,
430
- from_worker_rx,
431
- } = spawn_io_queue ( stdin, stdout, token. clone ( ) ) ;
432
-
433
- let ( command_tx, command_rx) = mpsc:: channel ( 8 ) ;
434
- let demultiplex_task = tokio:: spawn ( Commander :: demultiplex ( command_rx, from_worker_rx) ) ;
435
-
436
- let task = tokio:: spawn ( async move {
437
- let ( c, d, t) = join ! ( child. wait( ) , demultiplex_task, tasks. join_next( ) ) ;
438
- c. context ( JoinWorkerSnafu ) ?;
439
- d. context ( DemultiplexerTaskPanickedSnafu ) ?
440
- . context ( DemultiplexerTaskFailedSnafu ) ?;
441
- if let Some ( t) = t {
442
- t. context ( IoQueuePanickedSnafu ) ??;
443
- }
444
-
445
- Ok ( ( ) )
511
+ let [ stable, beta, nightly] = Channel :: ALL . map ( |channel| {
512
+ ContainerCore :: new ( channel, token. clone ( ) , & self . backend )
446
513
} ) ;
447
514
448
- let commander = Commander {
449
- to_worker_tx,
450
- to_demultiplexer_tx : command_tx,
451
- id : Default :: default ( ) ,
452
- } ;
453
-
454
515
Ok ( Container {
455
- task,
456
- commander,
516
+ stable : stable?,
517
+ beta : beta?,
518
+ nightly : nightly?,
457
519
token,
458
520
} )
459
521
}
@@ -466,9 +528,9 @@ impl Coordinator<DockerBackend> {
466
528
}
467
529
468
530
pub trait Backend {
469
- fn run_worker_in_background ( & self ) -> Result < ( Child , ChildStdin , ChildStdout ) > {
531
+ fn run_worker_in_background ( & self , channel : Channel ) -> Result < ( Child , ChildStdin , ChildStdout ) > {
470
532
let mut child = self
471
- . prepare_worker_command ( )
533
+ . prepare_worker_command ( channel )
472
534
. stdin ( Stdio :: piped ( ) )
473
535
. stdout ( Stdio :: piped ( ) )
474
536
. stderr ( Stdio :: inherit ( ) )
@@ -479,7 +541,7 @@ pub trait Backend {
479
541
Ok ( ( child, stdin, stdout) )
480
542
}
481
543
482
- fn prepare_worker_command ( & self ) -> Command ;
544
+ fn prepare_worker_command ( & self , channel : Channel ) -> Command ;
483
545
}
484
546
485
547
macro_rules! docker_command {
@@ -516,19 +578,29 @@ fn basic_secure_docker_command() -> Command {
516
578
pub struct DockerBackend ( ( ) ) ;
517
579
518
580
impl Backend for DockerBackend {
519
- fn prepare_worker_command ( & self ) -> Command {
581
+ fn prepare_worker_command ( & self , channel : Channel ) -> Command {
520
582
let mut command = basic_secure_docker_command ( ) ;
521
583
command
522
584
. arg ( "-i" )
523
585
. args ( [ "-a" , "stdin" , "-a" , "stdout" , "-a" , "stderr" ] )
524
586
. arg ( "--rm" )
525
- . arg ( "orchestrator" )
587
+ . arg ( channel . to_container_name ( ) )
526
588
. arg ( "worker" )
527
589
. arg ( "/playground" ) ;
528
590
command
529
591
}
530
592
}
531
593
594
+ impl Channel {
595
+ fn to_container_name ( & self ) -> & ' static str {
596
+ match self {
597
+ Channel :: Stable => "orchestrator-stable" ,
598
+ Channel :: Beta => "orchestrator-beta" ,
599
+ Channel :: Nightly => "orchestrator-nightly" ,
600
+ }
601
+ }
602
+ }
603
+
532
604
pub type Result < T , E = Error > = :: std:: result:: Result < T , E > ;
533
605
534
606
#[ derive( Debug , Snafu ) ]
@@ -681,7 +753,14 @@ mod tests {
681
753
}
682
754
683
755
impl Backend for TestBackend {
684
- fn prepare_worker_command ( & self ) -> Command {
756
+ fn prepare_worker_command ( & self , channel : Channel ) -> Command {
757
+ let toolchain_file = format ! ( r#"
758
+ [toolchain]
759
+ channel = "{}"
760
+ "# , channel. to_str( ) ) ;
761
+ let path = self . project_dir . path ( ) . join ( "rust-toolchain.toml" ) ;
762
+ std:: fs:: write ( path, toolchain_file) . expect ( "Couldn't write toolchain file" ) ;
763
+
685
764
let mut command = Command :: new ( "./target/debug/worker" ) ;
686
765
command. arg ( self . project_dir . path ( ) ) ;
687
766
command
0 commit comments