diff --git a/lib/loggers/file/src/logger.rs b/lib/loggers/file/src/logger.rs index 6241dbf..7896ece 100644 --- a/lib/loggers/file/src/logger.rs +++ b/lib/loggers/file/src/logger.rs @@ -4,7 +4,7 @@ // Created: // 10 Oct 2024, 14:16:24 // Last edited: -// 17 Oct 2024, 13:17:01 +// 05 Nov 2024, 10:43:25 // Auto updated? // Yes // @@ -124,7 +124,7 @@ pub struct FileLogger { path: PathBuf, /// Whether the user has already printed the context or not. #[cfg(debug_assertions)] - logged_context: bool, + logged_context: std::sync::Arc, } impl FileLogger { /// Constructor for the FileLogger that initializes it pointing to the given file. @@ -141,7 +141,7 @@ impl FileLogger { id: id.into(), path: path.into(), #[cfg(debug_assertions)] - logged_context: false, + logged_context: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)), } } @@ -202,7 +202,7 @@ impl AuditLogger for FileLogger { type Error = Error; #[inline] - fn log_context<'a, C>(&'a mut self, context: &'a C) -> impl 'a + Future> + fn log_context<'a, C>(&'a self, context: &'a C) -> impl 'a + Future> where C: ?Sized + Context, { @@ -215,14 +215,15 @@ impl AuditLogger for FileLogger { // Log it self.log(LogStatement::Context { context }).await?; - self.logged_context = true; + #[cfg(debug_assertions)] + self.logged_context.store(true, std::sync::atomic::Ordering::Relaxed); Ok(()) } } #[inline] fn log_response<'a, R>( - &'a mut self, + &'a self, reference: &'a str, response: &'a ReasonerResponse, raw: Option<&'a str>, @@ -232,7 +233,7 @@ impl AuditLogger for FileLogger { { async move { #[cfg(debug_assertions)] - if !self.logged_context { + if !self.logged_context.load(std::sync::atomic::Ordering::Relaxed) { tracing::warn!("Logging reasoner response without having logged the reasoner context; please call FileLogger::log_context() first."); } @@ -251,14 +252,14 @@ impl AuditLogger for FileLogger { } #[inline] - fn log_question<'a, S, Q>(&'a mut self, reference: &'a str, state: &'a S, question: &'a Q) -> impl 'a + Future> + fn log_question<'a, S, Q>(&'a self, reference: &'a str, state: &'a S, question: &'a Q) -> impl 'a + Future> where S: Serialize, Q: Serialize, { async move { #[cfg(debug_assertions)] - if !self.logged_context { + if !self.logged_context.load(std::sync::atomic::Ordering::Relaxed) { tracing::warn!("Logging reasoner response without having logged the reasoner context; please call FileLogger::log_context() first."); } diff --git a/lib/loggers/no-op/src/logger.rs b/lib/loggers/no-op/src/logger.rs index a579c34..5627526 100644 --- a/lib/loggers/no-op/src/logger.rs +++ b/lib/loggers/no-op/src/logger.rs @@ -4,7 +4,7 @@ // Created: // 10 Oct 2024, 14:46:33 // Last edited: -// 17 Oct 2024, 13:14:34 +// 05 Nov 2024, 10:23:27 // Auto updated? // Yes // @@ -41,7 +41,7 @@ impl AuditLogger for MockLogger { type Error = Infallible; #[inline] - fn log_context<'a, C>(&'a mut self, _context: &'a C) -> impl 'a + Future> + fn log_context<'a, C>(&'a self, _context: &'a C) -> impl 'a + Future> where C: ?Sized + Context, { @@ -53,7 +53,7 @@ impl AuditLogger for MockLogger { #[inline] fn log_response<'a, R>( - &'a mut self, + &'a self, _reference: &'a str, _response: &'a ReasonerResponse, _raw: Option<&'a str>, @@ -68,12 +68,7 @@ impl AuditLogger for MockLogger { } #[inline] - fn log_question<'a, S, Q>( - &'a mut self, - _reference: &'a str, - _state: &'a S, - _question: &'a Q, - ) -> impl 'a + Future> + fn log_question<'a, S, Q>(&'a self, _reference: &'a str, _state: &'a S, _question: &'a Q) -> impl 'a + Future> where S: Serialize, Q: Serialize, diff --git a/lib/reasoners/eflint-json/src/reasonerconn.rs b/lib/reasoners/eflint-json/src/reasonerconn.rs index 4934437..52ca0d7 100644 --- a/lib/reasoners/eflint-json/src/reasonerconn.rs +++ b/lib/reasoners/eflint-json/src/reasonerconn.rs @@ -4,7 +4,7 @@ // Created: // 09 Oct 2024, 15:52:06 // Last edited: -// 17 Oct 2024, 13:59:28 +// 05 Nov 2024, 10:44:14 // Auto updated? // Yes // @@ -216,7 +216,7 @@ where &self, state: Self::State, question: Self::Question, - logger: &mut SessionedAuditLogger, + logger: &SessionedAuditLogger, ) -> impl Future, Self::Error>> where L: AuditLogger, diff --git a/lib/reasoners/no-op/src/reasonerconn.rs b/lib/reasoners/no-op/src/reasonerconn.rs index ce020f9..999163f 100644 --- a/lib/reasoners/no-op/src/reasonerconn.rs +++ b/lib/reasoners/no-op/src/reasonerconn.rs @@ -4,7 +4,7 @@ // Created: // 10 Oct 2024, 16:21:09 // Last edited: -// 17 Oct 2024, 13:56:10 +// 05 Nov 2024, 10:43:39 // Auto updated? // Yes // @@ -80,7 +80,7 @@ where &self, state: Self::State, question: Self::Question, - logger: &mut SessionedAuditLogger, + logger: &SessionedAuditLogger, ) -> impl Future, Self::Error>> where L: AuditLogger, diff --git a/lib/reasoners/posix/src/reasonerconn.rs b/lib/reasoners/posix/src/reasonerconn.rs index 278dbd1..13739ed 100644 --- a/lib/reasoners/posix/src/reasonerconn.rs +++ b/lib/reasoners/posix/src/reasonerconn.rs @@ -4,7 +4,7 @@ // Created: // 11 Oct 2024, 16:54:51 // Last edited: -// 18 Oct 2024, 11:27:13 +// 05 Nov 2024, 10:44:07 // Auto updated? // Yes // @@ -256,7 +256,7 @@ impl ReasonerConnector for PosixReasonerConnector { &self, state: Self::State, _question: Self::Question, - logger: &mut SessionedAuditLogger, + logger: &SessionedAuditLogger, ) -> impl Future, Self::Error>> where L: AuditLogger, diff --git a/lib/spec/src/auditlogger.rs b/lib/spec/src/auditlogger.rs index fc297c8..554fa4b 100644 --- a/lib/spec/src/auditlogger.rs +++ b/lib/spec/src/auditlogger.rs @@ -4,7 +4,7 @@ // Created: // 09 Oct 2024, 13:38:41 // Last edited: -// 04 Nov 2024, 16:35:48 +// 05 Nov 2024, 10:23:16 // Auto updated? // Yes // @@ -57,14 +57,14 @@ impl SessionedAuditLogger { /// - `response`: The [`ReasonerResponse`] that we're logging. /// - `raw`: The raw response produced by the reasoner, if applicable. pub fn log_response<'a, R>( - &'a mut self, + &'a self, response: &'a ReasonerResponse, raw: Option<&'a str>, ) -> impl 'a + Future::Error>> where R: Display, { - L::log_response(&mut self.logger, &self.reference, response, raw) + L::log_response(&self.logger, &self.reference, response, raw) } /// Logs that the reasoner is being asked a question. @@ -72,26 +72,26 @@ impl SessionedAuditLogger { /// # Arguments /// - `state`: Some serializable state given as input to the reasoner. /// - `question`: Some serializable question that we're asking. - pub fn log_question<'a, S, Q>(&'a mut self, state: &'a S, question: &'a Q) -> impl 'a + Future::Error>> + pub fn log_question<'a, S, Q>(&'a self, state: &'a S, question: &'a Q) -> impl 'a + Future::Error>> where S: Serialize, Q: Serialize, { - L::log_question(&mut self.logger, &self.reference, state, question) + L::log_question(&self.logger, &self.reference, state, question) } } impl AuditLogger for SessionedAuditLogger { type Error = L::Error; - fn log_context<'a, C>(&'a mut self, context: &'a C) -> impl 'a + Future> + fn log_context<'a, C>(&'a self, context: &'a C) -> impl 'a + Future> where C: ?Sized + Context, { - L::log_context(&mut self.logger, context) + L::log_context(&self.logger, context) } fn log_response<'a, R>( - &'a mut self, + &'a self, reference: &'a str, response: &'a ReasonerResponse, raw: Option<&'a str>, @@ -99,15 +99,15 @@ impl AuditLogger for SessionedAuditLogger { where R: Display, { - L::log_response(&mut self.logger, reference, response, raw) + L::log_response(&self.logger, reference, response, raw) } - fn log_question<'a, S, Q>(&'a mut self, reference: &'a str, state: &'a S, question: &'a Q) -> impl 'a + Future> + fn log_question<'a, S, Q>(&'a self, reference: &'a str, state: &'a S, question: &'a Q) -> impl 'a + Future> where S: Serialize, Q: Serialize, { - L::log_question(&mut self.logger, reference, state, question) + L::log_question(&self.logger, reference, state, question) } } @@ -117,6 +117,8 @@ impl AuditLogger for SessionedAuditLogger { /***** LIBRARY *****/ /// Defines a generic interface to write to an audit trail. +/// +/// Note that this logger may be used across threads. As such, any mutability must be inferior. pub trait AuditLogger { /// Defines the errors returned by this logger. type Error: Error; @@ -126,7 +128,7 @@ pub trait AuditLogger { /// /// # Arguments /// - `context`: Something [`Serialize`]able that we want to write at startup. - fn log_context<'a, C>(&'a mut self, context: &'a C) -> impl 'a + Future> + fn log_context<'a, C>(&'a self, context: &'a C) -> impl 'a + Future> where C: ?Sized + Context; @@ -137,7 +139,7 @@ pub trait AuditLogger { /// - `response`: The [`ReasonerResponse`] that we're logging. /// - `raw`: The raw response produced by the reasoner, if applicable. fn log_response<'a, R>( - &'a mut self, + &'a self, reference: &'a str, response: &'a ReasonerResponse, raw: Option<&'a str>, @@ -151,18 +153,51 @@ pub trait AuditLogger { /// - `reference`: Some reference that links the response to a particular answer. /// - `state`: Some serializable state given as input to the reasoner. /// - `question`: Some serializable question that we're asking. - fn log_question<'a, S, Q>(&'a mut self, reference: &'a str, state: &'a S, question: &'a Q) -> impl 'a + Future> + fn log_question<'a, S, Q>(&'a self, reference: &'a str, state: &'a S, question: &'a Q) -> impl 'a + Future> where S: Serialize, Q: Serialize; } // Standard impls +impl<'a, T: AuditLogger> AuditLogger for &'a T { + type Error = T::Error; + + #[inline] + fn log_context<'s, C>(&'s self, context: &'s C) -> impl 's + Future> + where + C: ?Sized + Context, + { + ::log_context(self, context) + } + + #[inline] + fn log_response<'s, R>( + &'s self, + reference: &'s str, + response: &'s ReasonerResponse, + raw: Option<&'s str>, + ) -> impl 's + Future> + where + R: Display, + { + ::log_response(self, reference, response, raw) + } + + #[inline] + fn log_question<'s, S, Q>(&'s self, reference: &'s str, state: &'s S, question: &'s Q) -> impl 's + Future> + where + S: Serialize, + Q: Serialize, + { + ::log_question(self, reference, state, question) + } +} impl<'a, T: AuditLogger> AuditLogger for &'a mut T { type Error = T::Error; #[inline] - fn log_context<'s, C>(&'s mut self, context: &'s C) -> impl 's + Future> + fn log_context<'s, C>(&'s self, context: &'s C) -> impl 's + Future> where C: ?Sized + Context, { @@ -171,7 +206,7 @@ impl<'a, T: AuditLogger> AuditLogger for &'a mut T { #[inline] fn log_response<'s, R>( - &'s mut self, + &'s self, reference: &'s str, response: &'s ReasonerResponse, raw: Option<&'s str>, @@ -183,7 +218,7 @@ impl<'a, T: AuditLogger> AuditLogger for &'a mut T { } #[inline] - fn log_question<'s, S, Q>(&'s mut self, reference: &'s str, state: &'s S, question: &'s Q) -> impl 's + Future> + fn log_question<'s, S, Q>(&'s self, reference: &'s str, state: &'s S, question: &'s Q) -> impl 's + Future> where S: Serialize, Q: Serialize, diff --git a/lib/spec/src/reasonerconn.rs b/lib/spec/src/reasonerconn.rs index 23ab1ba..3969715 100644 --- a/lib/spec/src/reasonerconn.rs +++ b/lib/spec/src/reasonerconn.rs @@ -4,7 +4,7 @@ // Created: // 09 Oct 2024, 13:35:41 // Last edited: -// 17 Oct 2024, 09:50:17 +// 05 Nov 2024, 10:43:44 // Auto updated? // Yes // @@ -66,7 +66,7 @@ pub trait ReasonerConnector { &self, state: Self::State, question: Self::Question, - logger: &mut SessionedAuditLogger, + logger: &SessionedAuditLogger, ) -> impl Future, Self::Error>> where L: AuditLogger;