From 9f05061ce2621c6011ba00ebee79690388bb12f5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 27 Jul 2024 11:47:58 +0000 Subject: [PATCH] make event generation lazy Creating events if nobody is listening has always bugged me. --- examples/calc/db.rs | 3 ++- examples/lazy-input/main.rs | 3 ++- src/accumulator.rs | 2 +- src/database.rs | 8 ++++++-- src/function.rs | 2 +- src/function/diff_outputs.rs | 8 +++++--- src/function/execute.rs | 2 +- src/function/memo.rs | 2 +- src/handle.rs | 2 +- src/local_state.rs | 2 +- src/runtime.rs | 2 +- src/tracked_struct.rs | 2 +- tests/accumulate-from-tracked-fn.rs | 2 +- tests/accumulate-reuse-workaround.rs | 2 +- tests/accumulate-reuse.rs | 2 +- tests/accumulate.rs | 2 +- tests/deletion-cascade.rs | 3 ++- tests/deletion.rs | 3 ++- tests/parallel/setup.rs | 3 ++- tests/preverify-struct-with-leaked-data.rs | 3 ++- tests/tracked-struct-value-field-bad-eq.rs | 3 ++- 21 files changed, 37 insertions(+), 24 deletions(-) diff --git a/examples/calc/db.rs b/examples/calc/db.rs index 348adceb..35d47341 100644 --- a/examples/calc/db.rs +++ b/examples/calc/db.rs @@ -36,7 +36,8 @@ impl Database { // ANCHOR: db_impl #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, event: salsa::Event) { + fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { + let event = event(); eprintln!("Event: {event:?}"); // Log interesting events, if logging is enabled if let Some(logs) = &self.logs { diff --git a/examples/lazy-input/main.rs b/examples/lazy-input/main.rs index 7df78aa4..daf0c21c 100644 --- a/examples/lazy-input/main.rs +++ b/examples/lazy-input/main.rs @@ -124,8 +124,9 @@ impl Db for Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, event: salsa::Event) { + fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { // don't log boring events + let event = event(); if let salsa::EventKind::WillExecute { .. } = event.kind { self.logs.lock().unwrap().push(format!("{:?}", event)); } diff --git a/src/accumulator.rs b/src/accumulator.rs index 1e9c368d..dc114bb2 100644 --- a/src/accumulator.rs +++ b/src/accumulator.rs @@ -177,7 +177,7 @@ impl Ingredient for IngredientImpl { ) { assert!(stale_output_key.is_none()); if self.map.remove(&executor).is_some() { - db.salsa_event(Event { + db.salsa_event(&|| Event { thread_id: std::thread::current().id(), kind: EventKind::DidDiscardAccumulated { executor_key: executor, diff --git a/src/database.rs b/src/database.rs index ba39cf66..23606cfa 100644 --- a/src/database.rs +++ b/src/database.rs @@ -8,8 +8,12 @@ pub trait Database: ZalsaDatabase + AsDynDatabase { /// /// By default, the event is logged at level debug using /// the standard `log` facade. - fn salsa_event(&self, event: Event) { - tracing::debug!("salsa_event: {:?}", event) + /// + /// # Parameters + /// + /// * `event`, a fn that, if called, will create the event that occurred + fn salsa_event(&self, event: &dyn Fn() -> Event) { + tracing::debug!("salsa_event: {:?}", event()) } /// A "synthetic write" causes the system to act *as though* some diff --git a/src/function.rs b/src/function.rs index 3c95df59..72313cab 100644 --- a/src/function.rs +++ b/src/function.rs @@ -264,7 +264,7 @@ where if let Some(origin) = self.delete_memo(id) { let key = self.database_key_index(id); - db.salsa_event(Event { + db.salsa_event(&|| Event { thread_id: std::thread::current().id(), kind: EventKind::DidDiscard { key }, }); diff --git a/src/function/diff_outputs.rs b/src/function/diff_outputs.rs index 28617040..96df56f7 100644 --- a/src/function/diff_outputs.rs +++ b/src/function/diff_outputs.rs @@ -1,6 +1,6 @@ use crate::{ hash::FxHashSet, key::DependencyIndex, local_state::QueryRevisions, AsDynDatabase as _, - Database, DatabaseKeyIndex, Event, EventKind, + DatabaseKeyIndex, Event, EventKind, }; use super::{memo::Memo, Configuration, IngredientImpl}; @@ -38,7 +38,9 @@ where } fn report_stale_output(db: &C::DbView, key: DatabaseKeyIndex, output: DependencyIndex) { - db.salsa_event(Event { + let db = db.as_dyn_database(); + + db.salsa_event(&|| Event { thread_id: std::thread::current().id(), kind: EventKind::WillDiscardStaleOutput { execute_key: key, @@ -46,6 +48,6 @@ where }, }); - output.remove_stale_output(db.as_dyn_database(), key); + output.remove_stale_output(db, key); } } diff --git a/src/function/execute.rs b/src/function/execute.rs index 7cbbf62d..9ed1699e 100644 --- a/src/function/execute.rs +++ b/src/function/execute.rs @@ -32,7 +32,7 @@ where tracing::info!("{:?}: executing query", database_key_index); - db.salsa_event(Event { + db.salsa_event(&|| Event { thread_id: std::thread::current().id(), kind: EventKind::WillExecute { database_key: database_key_index, diff --git a/src/function/memo.rs b/src/function/memo.rs index ef26a014..4413d71a 100644 --- a/src/function/memo.rs +++ b/src/function/memo.rs @@ -149,7 +149,7 @@ impl Memo { revision_now: Revision, database_key_index: DatabaseKeyIndex, ) { - db.salsa_event(Event { + db.salsa_event(&|| Event { thread_id: std::thread::current().id(), kind: EventKind::DidValidateMemoizedValue { database_key: database_key_index, diff --git a/src/handle.rs b/src/handle.rs index 28661888..e3c2ecd9 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -80,7 +80,7 @@ impl Handle { let zalsa = self.db().zalsa(); zalsa.set_cancellation_flag(); - self.db().salsa_event(Event { + self.db().salsa_event(&|| Event { thread_id: std::thread::current().id(), kind: EventKind::DidSetCancellationFlag, diff --git a/src/local_state.rs b/src/local_state.rs index 4531809d..99f3d0da 100644 --- a/src/local_state.rs +++ b/src/local_state.rs @@ -317,7 +317,7 @@ impl LocalState { /// used instead. pub(crate) fn unwind_if_revision_cancelled(&self, db: &dyn Database) { let thread_id = std::thread::current().id(); - db.salsa_event(Event { + db.salsa_event(&|| Event { thread_id, kind: EventKind::WillCheckCancellation, diff --git a/src/runtime.rs b/src/runtime.rs index 3db4a6a6..3ac4ae8e 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -187,7 +187,7 @@ impl Runtime { assert!(!dg.depends_on(other_id, thread_id)); } - db.salsa_event(Event { + db.salsa_event(&|| Event { thread_id, kind: EventKind::WillBlockOn { other_thread_id: other_id, diff --git a/src/tracked_struct.rs b/src/tracked_struct.rs index 0621782b..45136529 100644 --- a/src/tracked_struct.rs +++ b/src/tracked_struct.rs @@ -394,7 +394,7 @@ where /// unspecified results (but not UB). See [`InternedIngredient::delete_index`] for more /// discussion and important considerations. pub(crate) fn delete_entity(&self, db: &dyn crate::Database, id: Id) { - db.salsa_event(Event { + db.salsa_event(&|| Event { thread_id: std::thread::current().id(), kind: crate::EventKind::DidDiscard { key: self.database_key_index(id), diff --git a/tests/accumulate-from-tracked-fn.rs b/tests/accumulate-from-tracked-fn.rs index a60f08b8..039b1a9b 100644 --- a/tests/accumulate-from-tracked-fn.rs +++ b/tests/accumulate-from-tracked-fn.rs @@ -52,7 +52,7 @@ struct Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, _event: salsa::Event) {} + fn salsa_event(&self, _event: &dyn Fn() -> salsa::Event) {} } #[salsa::db] diff --git a/tests/accumulate-reuse-workaround.rs b/tests/accumulate-reuse-workaround.rs index 8ba48f30..783ca0cc 100644 --- a/tests/accumulate-reuse-workaround.rs +++ b/tests/accumulate-reuse-workaround.rs @@ -59,7 +59,7 @@ struct Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, _event: salsa::Event) {} + fn salsa_event(&self, _event: &dyn Fn() -> salsa::Event) {} } #[salsa::db] diff --git a/tests/accumulate-reuse.rs b/tests/accumulate-reuse.rs index 37bfacaa..2075a8e7 100644 --- a/tests/accumulate-reuse.rs +++ b/tests/accumulate-reuse.rs @@ -50,7 +50,7 @@ struct Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, _event: salsa::Event) {} + fn salsa_event(&self, _event: &dyn Fn() -> salsa::Event) {} } #[salsa::db] diff --git a/tests/accumulate.rs b/tests/accumulate.rs index 3b6ce192..099128bd 100644 --- a/tests/accumulate.rs +++ b/tests/accumulate.rs @@ -65,7 +65,7 @@ struct Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, _event: salsa::Event) {} + fn salsa_event(&self, _event: &dyn Fn() -> salsa::Event) {} } #[salsa::db] diff --git a/tests/deletion-cascade.rs b/tests/deletion-cascade.rs index 1d65602f..8385d048 100644 --- a/tests/deletion-cascade.rs +++ b/tests/deletion-cascade.rs @@ -60,7 +60,8 @@ struct Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, event: salsa::Event) { + fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { + let event = event(); match event.kind { salsa::EventKind::WillDiscardStaleOutput { .. } | salsa::EventKind::DidDiscard { .. } => { diff --git a/tests/deletion.rs b/tests/deletion.rs index 78c0a58d..cdcc14bf 100644 --- a/tests/deletion.rs +++ b/tests/deletion.rs @@ -54,7 +54,8 @@ struct Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, event: salsa::Event) { + fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { + let event = event(); match event.kind { salsa::EventKind::WillDiscardStaleOutput { .. } | salsa::EventKind::DidDiscard { .. } => { diff --git a/tests/parallel/setup.rs b/tests/parallel/setup.rs index 94c31e50..c7c00ee8 100644 --- a/tests/parallel/setup.rs +++ b/tests/parallel/setup.rs @@ -37,7 +37,8 @@ pub(crate) struct Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, event: salsa::Event) { + fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { + let event = event(); match event.kind { salsa::EventKind::WillBlockOn { .. } => { self.signal(self.knobs().signal_on_will_block.load()); diff --git a/tests/preverify-struct-with-leaked-data.rs b/tests/preverify-struct-with-leaked-data.rs index 0f52ea0f..2e311c6f 100644 --- a/tests/preverify-struct-with-leaked-data.rs +++ b/tests/preverify-struct-with-leaked-data.rs @@ -25,7 +25,8 @@ struct Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, event: salsa::Event) { + fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { + let event = event(); self.push_log(format!("{event:?}")); } } diff --git a/tests/tracked-struct-value-field-bad-eq.rs b/tests/tracked-struct-value-field-bad-eq.rs index 3759c912..a9d50c6f 100644 --- a/tests/tracked-struct-value-field-bad-eq.rs +++ b/tests/tracked-struct-value-field-bad-eq.rs @@ -61,7 +61,8 @@ struct Database { #[salsa::db] impl salsa::Database for Database { - fn salsa_event(&self, event: salsa::Event) { + fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { + let event = event(); match event.kind { salsa::EventKind::WillExecute { .. } | salsa::EventKind::DidValidateMemoizedValue { .. } => {