65
65
//! [`IndexSummary::parse`]: super::IndexSummary::parse
66
66
//! [`RemoteRegistry`]: crate::sources::registry::remote::RemoteRegistry
67
67
68
+ use std:: cell:: RefCell ;
68
69
use std:: fs;
69
70
use std:: io;
70
71
use std:: path:: PathBuf ;
@@ -226,14 +227,21 @@ pub struct CacheManager<'gctx> {
226
227
cache_root : Filesystem ,
227
228
/// [`GlobalContext`] reference for convenience.
228
229
gctx : & ' gctx GlobalContext ,
230
+ /// Keeps track of if we have sent a warning message if there was an error updating the cache.
231
+ /// The motivation is to avoid warning spam if the cache is not writable.
232
+ has_warned : RefCell < bool > ,
229
233
}
230
234
231
235
impl < ' gctx > CacheManager < ' gctx > {
232
236
/// Creates a new instance of the on-disk index cache manager.
233
237
///
234
238
/// `root` --- The root path where caches are located.
235
239
pub fn new ( cache_root : Filesystem , gctx : & ' gctx GlobalContext ) -> CacheManager < ' gctx > {
236
- CacheManager { cache_root, gctx }
240
+ CacheManager {
241
+ cache_root,
242
+ gctx,
243
+ has_warned : Default :: default ( ) ,
244
+ }
237
245
}
238
246
239
247
/// Gets the cache associated with the key.
@@ -251,16 +259,28 @@ impl<'gctx> CacheManager<'gctx> {
251
259
/// Associates the value with the key.
252
260
pub fn put ( & self , key : & str , value : & [ u8 ] ) {
253
261
let cache_path = & self . cache_path ( key) ;
254
- if fs:: create_dir_all ( cache_path. parent ( ) . unwrap ( ) ) . is_ok ( ) {
255
- let path = Filesystem :: new ( cache_path. clone ( ) ) ;
256
- self . gctx
257
- . assert_package_cache_locked ( CacheLockMode :: DownloadExclusive , & path) ;
258
- if let Err ( e) = fs:: write ( cache_path, value) {
259
- tracing:: info!( ?cache_path, "failed to write cache: {e}" ) ;
262
+ if let Err ( e) = self . put_inner ( cache_path, value) {
263
+ tracing:: info!( ?cache_path, "failed to write cache: {e}" ) ;
264
+
265
+ if !* self . has_warned . borrow ( ) {
266
+ let _ = self . gctx . shell ( ) . warn ( format ! (
267
+ "failed to write cache, path: {}, error: {e}" ,
268
+ cache_path. to_str( ) . unwrap_or_default( )
269
+ ) ) ;
270
+ * self . has_warned . borrow_mut ( ) = true ;
260
271
}
261
272
}
262
273
}
263
274
275
+ fn put_inner ( & self , cache_path : & PathBuf , value : & [ u8 ] ) -> std:: io:: Result < ( ) > {
276
+ fs:: create_dir_all ( cache_path. parent ( ) . unwrap ( ) ) ?;
277
+ let path = Filesystem :: new ( cache_path. clone ( ) ) ;
278
+ self . gctx
279
+ . assert_package_cache_locked ( CacheLockMode :: DownloadExclusive , & path) ;
280
+ fs:: write ( cache_path, value) ?;
281
+ Ok ( ( ) )
282
+ }
283
+
264
284
/// Invalidates the cache associated with the key.
265
285
pub fn invalidate ( & self , key : & str ) {
266
286
let cache_path = & self . cache_path ( key) ;
0 commit comments