@@ -2,13 +2,13 @@ use std::{
2
2
collections:: HashMap ,
3
3
ffi:: OsString ,
4
4
io:: { Cursor , Read } ,
5
+ mem:: drop,
5
6
path:: PathBuf ,
6
7
sync:: Arc ,
7
8
time:: UNIX_EPOCH ,
8
9
} ;
9
10
10
11
use base64:: { engine:: general_purpose:: STANDARD as BASE64_STD , Engine } ;
11
- use dashmap:: DashMap ;
12
12
use derive_more:: { Display , Error , From } ;
13
13
use miette:: Diagnostic ;
14
14
use pacquet_fs:: file_mode;
@@ -88,7 +88,7 @@ pub enum CacheValue {
88
88
/// Internal in-memory cache of tarballs.
89
89
///
90
90
/// The key of this hashmap is the url of each tarball.
91
- pub type MemCache = DashMap < String , Arc < RwLock < CacheValue > > > ;
91
+ pub type MemCache = RwLock < HashMap < String , Arc < RwLock < CacheValue > > > > ;
92
92
93
93
#[ instrument( skip( gz_data) , fields( gz_data_len = gz_data. len( ) ) ) ]
94
94
fn decompress_gzip ( gz_data : & [ u8 ] , unpacked_size : Option < usize > ) -> Result < Vec < u8 > , TarballError > {
@@ -130,9 +130,9 @@ impl<'a> DownloadTarballToStore<'a> {
130
130
131
131
// QUESTION: I see no copying from existing store_dir, is there such mechanism?
132
132
// TODO: If it's not implemented yet, implement it
133
-
134
- if let Some ( cache_lock) = mem_cache . get ( package_url) {
135
- let notify = match & * cache_lock. write ( ) . await {
133
+ let mem_cache_reader = mem_cache . read ( ) . await ;
134
+ if let Some ( cache_lock) = mem_cache_reader . get ( package_url) {
135
+ let notify = match & * cache_lock. read ( ) . await {
136
136
CacheValue :: Available ( cas_paths) => {
137
137
return Ok ( Arc :: clone ( cas_paths) ) ;
138
138
}
@@ -146,13 +146,19 @@ impl<'a> DownloadTarballToStore<'a> {
146
146
}
147
147
unreachable ! ( "Failed to get or compute tarball data for {package_url:?}" ) ;
148
148
} else {
149
+ drop ( mem_cache_reader) ;
149
150
let notify = Arc :: new ( Notify :: new ( ) ) ;
150
151
let cache_lock = notify
151
152
. pipe_ref ( Arc :: clone)
152
153
. pipe ( CacheValue :: InProgress )
153
154
. pipe ( RwLock :: new)
154
155
. pipe ( Arc :: new) ;
155
- if mem_cache. insert ( package_url. to_string ( ) , Arc :: clone ( & cache_lock) ) . is_some ( ) {
156
+ if mem_cache
157
+ . write ( )
158
+ . await
159
+ . insert ( package_url. to_string ( ) , Arc :: clone ( & cache_lock) )
160
+ . is_some ( )
161
+ {
156
162
tracing:: warn!( target: "pacquet::download" , ?package_url, "Race condition detected when writing to cache" ) ;
157
163
}
158
164
let cas_paths = self . run_without_mem_cache ( ) . await ?. pipe ( Arc :: new) ;
0 commit comments