fix(discord): use channel_id instead of sender for replies (fixes #483)
fix(misc): complete parking_lot::Mutex migration (fixes #505) - DiscordChannel: store actual channel_id in ChannelMessage.channel instead of hardcoded "discord" string - channels/mod.rs: use msg.channel instead of msg.sender for replies - Migrate all std::sync::Mutex to parking_lot::Mutex: * src/security/audit.rs * src/memory/sqlite.rs * src/memory/response_cache.rs * src/memory/lucid.rs * src/channels/email_channel.rs * src/gateway/mod.rs * src/observability/traits.rs * src/providers/reliable.rs * src/providers/router.rs * src/agent/agent.rs - Remove all .lock().unwrap() and .map_err(PoisonError) patterns since parking_lot::Mutex never poisons Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f7d77b09f4
commit
1908af3248
12 changed files with 43 additions and 61 deletions
|
|
@ -4,7 +4,7 @@ use async_trait::async_trait;
|
|||
use chrono::Local;
|
||||
use std::collections::HashSet;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
use parking_lot::Mutex;
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio::process::Command;
|
||||
use tokio::time::timeout;
|
||||
|
|
@ -113,9 +113,7 @@ impl LucidMemory {
|
|||
}
|
||||
|
||||
fn in_failure_cooldown(&self) -> bool {
|
||||
let Ok(guard) = self.last_failure_at.lock() else {
|
||||
return false;
|
||||
};
|
||||
let guard = self.last_failure_at.lock();
|
||||
|
||||
guard
|
||||
.as_ref()
|
||||
|
|
@ -123,15 +121,11 @@ impl LucidMemory {
|
|||
}
|
||||
|
||||
fn mark_failure_now(&self) {
|
||||
if let Ok(mut guard) = self.last_failure_at.lock() {
|
||||
*guard = Some(Instant::now());
|
||||
}
|
||||
*self.last_failure_at.lock() = Some(Instant::now());
|
||||
}
|
||||
|
||||
fn clear_failure(&self) {
|
||||
if let Ok(mut guard) = self.last_failure_at.lock() {
|
||||
*guard = None;
|
||||
}
|
||||
*self.last_failure_at.lock() = None;
|
||||
}
|
||||
|
||||
fn to_lucid_type(category: &MemoryCategory) -> &'static str {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use chrono::{Duration, Local};
|
|||
use rusqlite::{params, Connection};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
/// Response cache backed by a dedicated SQLite database.
|
||||
///
|
||||
|
|
@ -77,10 +77,7 @@ impl ResponseCache {
|
|||
|
||||
/// Look up a cached response. Returns `None` on miss or expired entry.
|
||||
pub fn get(&self, key: &str) -> Result<Option<String>> {
|
||||
let conn = self
|
||||
.conn
|
||||
.lock()
|
||||
.map_err(|e| anyhow::anyhow!("Lock error: {e}"))?;
|
||||
let conn = self.conn.lock();
|
||||
|
||||
let now = Local::now();
|
||||
let cutoff = (now - Duration::minutes(self.ttl_minutes)).to_rfc3339();
|
||||
|
|
@ -108,10 +105,7 @@ impl ResponseCache {
|
|||
|
||||
/// Store a response in the cache.
|
||||
pub fn put(&self, key: &str, model: &str, response: &str, token_count: u32) -> Result<()> {
|
||||
let conn = self
|
||||
.conn
|
||||
.lock()
|
||||
.map_err(|e| anyhow::anyhow!("Lock error: {e}"))?;
|
||||
let conn = self.conn.lock();
|
||||
|
||||
let now = Local::now().to_rfc3339();
|
||||
|
||||
|
|
@ -146,10 +140,7 @@ impl ResponseCache {
|
|||
|
||||
/// Return cache statistics: (total_entries, total_hits, total_tokens_saved).
|
||||
pub fn stats(&self) -> Result<(usize, u64, u64)> {
|
||||
let conn = self
|
||||
.conn
|
||||
.lock()
|
||||
.map_err(|e| anyhow::anyhow!("Lock error: {e}"))?;
|
||||
let conn = self.conn.lock();
|
||||
|
||||
let count: i64 =
|
||||
conn.query_row("SELECT COUNT(*) FROM response_cache", [], |row| row.get(0))?;
|
||||
|
|
@ -172,10 +163,7 @@ impl ResponseCache {
|
|||
|
||||
/// Wipe the entire cache (useful for `zeroclaw cache clear`).
|
||||
pub fn clear(&self) -> Result<usize> {
|
||||
let conn = self
|
||||
.conn
|
||||
.lock()
|
||||
.map_err(|e| anyhow::anyhow!("Lock error: {e}"))?;
|
||||
let conn = self.conn.lock();
|
||||
|
||||
let affected = conn.execute("DELETE FROM response_cache", [])?;
|
||||
Ok(affected)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ use async_trait::async_trait;
|
|||
use chrono::Local;
|
||||
use rusqlite::{params, Connection};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use parking_lot::Mutex;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// SQLite-backed persistent memory — the brain
|
||||
|
|
@ -896,7 +897,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn schema_has_fts5_table() {
|
||||
let (_tmp, mem) = temp_sqlite();
|
||||
let conn = mem.conn.lock().unwrap();
|
||||
let conn = mem.conn.lock();
|
||||
// FTS5 table should exist
|
||||
let count: i64 = conn
|
||||
.query_row(
|
||||
|
|
@ -911,7 +912,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn schema_has_embedding_cache() {
|
||||
let (_tmp, mem) = temp_sqlite();
|
||||
let conn = mem.conn.lock().unwrap();
|
||||
let conn = mem.conn.lock();
|
||||
let count: i64 = conn
|
||||
.query_row(
|
||||
"SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='embedding_cache'",
|
||||
|
|
@ -925,7 +926,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn schema_memories_has_embedding_column() {
|
||||
let (_tmp, mem) = temp_sqlite();
|
||||
let conn = mem.conn.lock().unwrap();
|
||||
let conn = mem.conn.lock();
|
||||
// Check that embedding column exists by querying it
|
||||
let result = conn.execute_batch("SELECT embedding FROM memories LIMIT 0");
|
||||
assert!(result.is_ok());
|
||||
|
|
@ -940,7 +941,7 @@ mod tests {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
let conn = mem.conn.lock().unwrap();
|
||||
let conn = mem.conn.lock();
|
||||
let count: i64 = conn
|
||||
.query_row(
|
||||
"SELECT COUNT(*) FROM memories_fts WHERE memories_fts MATCH '\"unique_searchterm_xyz\"'",
|
||||
|
|
@ -959,7 +960,7 @@ mod tests {
|
|||
.unwrap();
|
||||
mem.forget("del_key").await.unwrap();
|
||||
|
||||
let conn = mem.conn.lock().unwrap();
|
||||
let conn = mem.conn.lock();
|
||||
let count: i64 = conn
|
||||
.query_row(
|
||||
"SELECT COUNT(*) FROM memories_fts WHERE memories_fts MATCH '\"deletable_content_abc\"'",
|
||||
|
|
@ -980,7 +981,7 @@ mod tests {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
let conn = mem.conn.lock().unwrap();
|
||||
let conn = mem.conn.lock();
|
||||
// Old content should not be findable
|
||||
let old: i64 = conn
|
||||
.query_row(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue