Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: put PackageCache into an enum in preparation for a multi-layered package cache #843

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion crates/rattler-bin/src/commands/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ pub async fn create(opt: Opt) -> anyhow::Result<()> {
// Get the package names from the matchspecs so we can only load the package records that we need.
let gateway = Gateway::builder()
.with_cache_dir(cache_dir.join(rattler_cache::REPODATA_CACHE_DIR))
.with_package_cache(PackageCache::new(
.with_package_cache(PackageCache::new_singleton(
cache_dir.join(rattler_cache::PACKAGE_CACHE_DIR),
))
.with_client(download_client.clone())
Expand Down
16 changes: 8 additions & 8 deletions crates/rattler/src/install/clobber_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ mod tests {
let target_prefix = tempfile::tempdir().unwrap();

let packages_dir = tempfile::tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

execute_transaction(
transaction,
Expand Down Expand Up @@ -597,7 +597,7 @@ mod tests {
let target_prefix = tempfile::tempdir().unwrap();

let packages_dir = tempfile::tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

execute_transaction(
transaction,
Expand Down Expand Up @@ -679,7 +679,7 @@ mod tests {
let target_prefix = tempfile::tempdir().unwrap();

let packages_dir = tempfile::tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

execute_transaction(
transaction,
Expand Down Expand Up @@ -782,7 +782,7 @@ mod tests {
let target_prefix = tempfile::tempdir().unwrap();

let packages_dir = tempfile::tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

execute_transaction(
transaction,
Expand Down Expand Up @@ -883,7 +883,7 @@ mod tests {
let target_prefix = tempfile::tempdir().unwrap();

let packages_dir = tempfile::tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

execute_transaction(
transaction,
Expand Down Expand Up @@ -1013,7 +1013,7 @@ mod tests {
let target_prefix = tempfile::tempdir().unwrap();

let packages_dir = tempfile::tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

let install_options = InstallOptions {
python_info: Some(python_info.clone()),
Expand Down Expand Up @@ -1062,7 +1062,7 @@ mod tests {
let target_prefix = tempfile::tempdir().unwrap();

let packages_dir = tempfile::tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

execute_transaction(
transaction,
Expand Down Expand Up @@ -1129,7 +1129,7 @@ mod tests {
let target_prefix = tempfile::tempdir().unwrap();

let packages_dir = tempfile::tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

execute_transaction(
transaction,
Expand Down
2 changes: 1 addition & 1 deletion crates/rattler/src/install/installer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ impl Installer {
.downloader
.unwrap_or_else(|| reqwest_middleware::ClientWithMiddleware::from(Client::default()));
let package_cache = self.package_cache.unwrap_or_else(|| {
PackageCache::new(
PackageCache::new_singleton(
default_cache_dir()
.expect("failed to determine default cache directory")
.join(rattler_cache::PACKAGE_CACHE_DIR),
Expand Down
2 changes: 1 addition & 1 deletion crates/rattler/src/install/link_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ mod tests {
};

let packages_dir = tempfile::tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());
let driver = InstallDriver::builder().execute_link_scripts(true).finish();

execute_transaction(
Expand Down
3 changes: 2 additions & 1 deletion crates/rattler/src/install/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,8 @@ mod test {
// Open a package cache in the systems temporary directory with a specific name.
// This allows us to reuse a package cache across multiple invocations
// of this test. Useful if you're debugging.
let package_cache = PackageCache::new(temp_dir().join("rattler").join(cache_name));
let package_cache =
PackageCache::new_singleton(temp_dir().join("rattler").join(cache_name));

// Create an HTTP client we can use to download packages
let client = reqwest_middleware::ClientWithMiddleware::from(reqwest::Client::new());
Expand Down
27 changes: 18 additions & 9 deletions crates/rattler_cache/src/package_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ pub trait CacheReporter: Send + Sync {
/// cache is stale a user defined function is called to populate the cache. This
/// separates the corners between caching and fetching of the content.
#[derive(Clone)]
pub struct PackageCache {
inner: Arc<Mutex<PackageCacheInner>>,
pub enum PackageCache {
/// A package cache which reads/writes from only one directory.
SingletonPackageCache {
inner: Arc<Mutex<PackageCacheInner>>,
},
}

/// Provides a unique identifier for packages in the cache.
Expand Down Expand Up @@ -112,7 +115,7 @@ impl Display for CacheKey {
}

#[derive(Default)]
struct PackageCacheInner {
pub struct PackageCacheInner {
path: PathBuf,
packages: FxHashMap<CacheKey, Arc<Mutex<Package>>>,
}
Expand All @@ -133,16 +136,21 @@ pub enum PackageCacheError {
}

impl PackageCache {
/// Constructs a new [`PackageCache`] located at the specified path.
pub fn new(path: impl Into<PathBuf>) -> Self {
Self {
pub fn new_singleton(path: impl Into<PathBuf>) -> Self {
Self::SingletonPackageCache {
inner: Arc::new(Mutex::new(PackageCacheInner {
path: path.into(),
packages: FxHashMap::default(),
})),
}
}

fn get_inner(&self) -> Arc<Mutex<PackageCacheInner>> {
match self {
Self::SingletonPackageCache { inner } => inner.clone(),
}
}

/// Returns the directory that contains the specified package.
///
/// If the package was previously successfully fetched and stored in the
Expand All @@ -168,7 +176,8 @@ impl PackageCache {

// Get the package entry
let (package, pkg_cache_dir) = {
let mut inner = self.inner.lock();
let _inner = self.get_inner();
let mut inner = _inner.lock();
let destination = inner.path.join(cache_key.to_string());
let package = inner.packages.entry(cache_key).or_default().clone();
(package, destination)
Expand Down Expand Up @@ -455,7 +464,7 @@ mod test {
};

let packages_dir = tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

// Get the package to the cache
let package_dir = cache
Expand Down Expand Up @@ -590,7 +599,7 @@ mod test {
tokio::spawn(axum::serve(listener, service).into_future());

let packages_dir = tempdir().unwrap();
let cache = PackageCache::new(packages_dir.path());
let cache = PackageCache::new_singleton(packages_dir.path());

let server_url = Url::parse(&format!("http://localhost:{}", addr.port())).unwrap();

Expand Down
2 changes: 1 addition & 1 deletion crates/rattler_repodata_gateway/src/gateway/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl GatewayBuilder {
.join("rattler/cache")
});

let package_cache = self.package_cache.unwrap_or(PackageCache::new(
let package_cache = self.package_cache.unwrap_or(PackageCache::new_singleton(
cache.join(rattler_cache::PACKAGE_CACHE_DIR),
));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ mod test {
"https://conda.anaconda.org/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_0.conda",
)
.unwrap();
let package_cache = PackageCache::new(PathBuf::from("/tmp"));
let package_cache = PackageCache::new_singleton(PathBuf::from("/tmp"));
let client = reqwest_middleware::ClientWithMiddleware::from(reqwest::Client::new());
let query = DirectUrlQuery::new(url.clone(), package_cache, client, None);

Expand Down Expand Up @@ -163,7 +163,7 @@ mod test {
.unwrap();

let url = Url::from_file_path(package_path).unwrap();
let package_cache = PackageCache::new(temp_dir());
let package_cache = PackageCache::new_singleton(temp_dir());
let client = reqwest_middleware::ClientWithMiddleware::from(reqwest::Client::new());
let query = DirectUrlQuery::new(url.clone(), package_cache, client, None);

Expand Down
4 changes: 2 additions & 2 deletions crates/rattler_repodata_gateway/src/gateway/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ mod test {
#[tokio::test]
async fn test_direct_url_spec_from_gateway() {
let gateway = Gateway::builder()
.with_package_cache(PackageCache::new(
.with_package_cache(PackageCache::new_singleton(
default_cache_dir()
.unwrap()
.join(rattler_cache::PACKAGE_CACHE_DIR),
Expand Down Expand Up @@ -494,7 +494,7 @@ mod test {
#[tokio::test]
async fn test_select_forced_url_instead_of_deps() {
let gateway = Gateway::builder()
.with_package_cache(PackageCache::new(
.with_package_cache(PackageCache::new_singleton(
default_cache_dir()
.unwrap()
.join(rattler_cache::PACKAGE_CACHE_DIR),
Expand Down
2 changes: 1 addition & 1 deletion py-rattler/src/installer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub fn py_install<'a>(
}

if let Some(cache_dir) = cache_dir {
installer.set_package_cache(PackageCache::new(cache_dir));
installer.set_package_cache(PackageCache::new_singleton(cache_dir));
}

if let Some(installed_packages) = installed_packages {
Expand Down