6565//! [`IndexSummary::parse`]: super::IndexSummary::parse
6666//! [`RemoteRegistry`]: crate::sources::registry::remote::RemoteRegistry
6767
68+ use std:: cell:: RefCell ;
6869use std:: fs;
6970use std:: io;
7071use std:: path:: PathBuf ;
@@ -226,14 +227,21 @@ pub struct CacheManager<'gctx> {
226227 cache_root : Filesystem ,
227228 /// [`GlobalContext`] reference for convenience.
228229 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 > ,
229233}
230234
231235impl < ' gctx > CacheManager < ' gctx > {
232236 /// Creates a new instance of the on-disk index cache manager.
233237 ///
234238 /// `root` --- The root path where caches are located.
235239 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+ }
237245 }
238246
239247 /// Gets the cache associated with the key.
@@ -251,16 +259,28 @@ impl<'gctx> CacheManager<'gctx> {
251259 /// Associates the value with the key.
252260 pub fn put ( & self , key : & str , value : & [ u8 ] ) {
253261 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 ;
260271 }
261272 }
262273 }
263274
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+
264284 /// Invalidates the cache associated with the key.
265285 pub fn invalidate ( & self , key : & str ) {
266286 let cache_path = & self . cache_path ( key) ;
0 commit comments