@@ -5,6 +5,7 @@ use dkregistry::v2::manifest::{Manifest, RuntimeConfig};
5
5
use std:: {
6
6
collections:: { BTreeMap , HashMap } ,
7
7
path:: { Path , PathBuf } ,
8
+ sync:: Mutex ,
8
9
} ;
9
10
10
11
#[ derive( Clone ) ]
@@ -58,7 +59,7 @@ pub struct ToolchainPuller {
58
59
// TODO: per-registry options
59
60
disable_tls : bool ,
60
61
/// Cache for already pulled toolchains.
61
- cache : HashMap < String , PulledToolchain > ,
62
+ cache : Mutex < HashMap < String , PulledToolchain > > ,
62
63
}
63
64
64
65
impl ToolchainPuller {
@@ -76,7 +77,7 @@ impl ToolchainPuller {
76
77
image_puller,
77
78
toolchains_dir : tooclhains_dir. to_path_buf ( ) ,
78
79
disable_tls,
79
- cache : HashMap :: new ( ) ,
80
+ cache : Mutex :: new ( HashMap :: new ( ) ) ,
80
81
} )
81
82
}
82
83
@@ -153,8 +154,13 @@ impl ToolchainPuller {
153
154
154
155
#[ tracing:: instrument( skip( self ) ) ]
155
156
pub async fn resolve ( & self , toolchain_image : & str ) -> anyhow:: Result < PulledToolchain > {
156
- if let Some ( info) = self . cache . get ( toolchain_image) {
157
- return Ok ( info. clone ( ) ) ;
157
+ {
158
+ // TODO: do not pull one image concurrently, instead one task should pull
159
+ // ond other should wait.
160
+ let cache = self . cache . lock ( ) . unwrap ( ) ;
161
+ if let Some ( info) = cache. get ( toolchain_image) {
162
+ return Ok ( info. clone ( ) ) ;
163
+ }
158
164
}
159
165
let dirname = base64:: encode ( toolchain_image) ;
160
166
let toolchain_dir = self . toolchains_dir . join ( & dirname) ;
@@ -164,9 +170,14 @@ impl ToolchainPuller {
164
170
. await
165
171
. context ( "toolchain download error" ) ?;
166
172
167
- Ok ( PulledToolchain {
173
+ let pt = PulledToolchain {
168
174
path : dirname,
169
175
image_config,
170
- } )
176
+ } ;
177
+ {
178
+ let mut cache = self . cache . lock ( ) . unwrap ( ) ;
179
+ cache. insert ( toolchain_image. to_string ( ) , pt. clone ( ) ) ;
180
+ }
181
+ Ok ( pt)
171
182
}
172
183
}
0 commit comments