From d71409950156a0b5eaafbe6914f0516b5175dfd4 Mon Sep 17 00:00:00 2001 From: Jonathan Cammisuli Date: Fri, 4 Oct 2024 15:16:03 -0400 Subject: [PATCH] fix(core): handle unique constraint errors when adding duplicate hashes to the cache db (#28310) ## Current Behavior ## Expected Behavior ## Related Issue(s) Fixes # --- packages/nx/src/native/cache/cache.rs | 31 ++++++++-------------- packages/nx/src/native/tests/cache.spec.ts | 5 ++++ 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/packages/nx/src/native/cache/cache.rs b/packages/nx/src/native/cache/cache.rs index 866a9527faec23..16ce0daf303083 100644 --- a/packages/nx/src/native/cache/cache.rs +++ b/packages/nx/src/native/cache/cache.rs @@ -48,7 +48,7 @@ impl NxCache { workspace_root: PathBuf::from(workspace_root), cache_directory: cache_path.to_normalized_string(), cache_path, - link_task_details: link_task_details.unwrap_or(true) + link_task_details: link_task_details.unwrap_or(true), }; r.setup()?; @@ -80,11 +80,7 @@ impl NxCache { " }; - self.db - .execute_batch( - query, - ) - .map_err(anyhow::Error::from) + self.db.execute_batch(query).map_err(anyhow::Error::from) } #[napi] @@ -144,7 +140,7 @@ impl NxCache { create_dir_all(&task_dir)?; // Write the terminal outputs into a file - let task_outputs_path: _ = self.get_task_outputs_path_internal(&hash); + let task_outputs_path = self.get_task_outputs_path_internal(&hash); trace!("Writing terminal outputs to: {:?}", &task_outputs_path); write(task_outputs_path, terminal_output)?; @@ -192,9 +188,7 @@ impl NxCache { fn record_to_cache(&self, hash: String, code: i16) -> anyhow::Result<()> { self.db.execute( - "INSERT INTO cache_outputs - (hash, code) - VALUES (?1, ?2)", + "INSERT OR REPLACE INTO cache_outputs (hash, code) VALUES (?1, ?2)", params![hash, code], )?; Ok(()) @@ -258,19 +252,16 @@ impl NxCache { // Checks that the number of cache records in the database // matches the number of cache directories on the filesystem. // If they don't match, it means that the cache is out of sync. - let cache_records_exist = self.db.query_row( - "SELECT EXISTS (SELECT 1 FROM cache_outputs)", - [], - |row| { - let exists: bool = row.get(0)?; - Ok(exists) - }, - )?; + let cache_records_exist = + self.db + .query_row("SELECT EXISTS (SELECT 1 FROM cache_outputs)", [], |row| { + let exists: bool = row.get(0)?; + Ok(exists) + })?; if !cache_records_exist { let hash_regex = Regex::new(r"^\d+$").expect("Hash regex is invalid"); - let fs_entries = std::fs::read_dir(&self.cache_path) - .map_err(anyhow::Error::from)?; + let fs_entries = std::fs::read_dir(&self.cache_path).map_err(anyhow::Error::from)?; for entry in fs_entries { let entry = entry?; diff --git a/packages/nx/src/native/tests/cache.spec.ts b/packages/nx/src/native/tests/cache.spec.ts index 068f7b72b6f12f..b465ceba8078b3 100644 --- a/packages/nx/src/native/tests/cache.spec.ts +++ b/packages/nx/src/native/tests/cache.spec.ts @@ -59,4 +59,9 @@ describe('Cache', () => { 'output contents 123' ); }); + + it('should handle storing hashes that already exist in the cache', async () => { + cache.put('123', 'output 123', ['dist'], 0); + expect(() => cache.put('123', 'output 123', ['dist'], 0)).not.toThrow(); + }); });