memoryd: memory writes decided into the Honcho ledger as they are journalled

Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
2026-09-28 12:46:18 -07:00
co-authored by ornith-1.5-35b-a3b
parent b37eaef390
commit 4ebfc36c1a
8 changed files with 862 additions and 23 deletions
+28 -11
View File
@@ -6,7 +6,7 @@
//! the worker decides what `brokerd` could not answer for before, then sleeps until a turn ends.
use std::collections::HashSet;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Condvar, Mutex};
use std::time::Duration;
@@ -20,6 +20,7 @@ use crate::honcho::client::{Clients, HonchoError, Timeouts, classify};
use crate::honcho::config::HonchoConfig;
use crate::honcho::decide::{final_reply, turn_records, user_text};
use crate::honcho::ledger::{self, Action, Item, Ledger, Record, Workspace};
use crate::honcho::mirror::Mirror;
use crate::honcho::naming::{HonchoSession, honcho_session};
use crate::honcho::state;
use crate::honcho::turns::{LEDGER, TurnSync, log_path, read_log};
@@ -114,6 +115,9 @@ struct Next {
pub struct Worker {
sync: Arc<Mutex<TurnSync>>,
/// The ledger's own lock (task 12): taken alone, briefly, never with `sync`'s.
ledger: Arc<Mutex<Ledger>>,
sessions: PathBuf,
clients: Clients,
wake: Arc<Wake>,
ask: AskBox,
@@ -185,8 +189,14 @@ impl Worker {
tuning: Tuning,
agent: &str,
) -> Worker {
let (ledger, sessions) = {
let sync = sync.lock().unwrap_or_else(|p| p.into_inner());
(sync.shared_ledger(), sync.sessions().to_path_buf())
};
Worker {
sync,
ledger,
sessions,
clients,
wake,
ask,
@@ -279,8 +289,7 @@ impl Worker {
/// The oldest waiting turn whose workspace's key was not refused. Other actions wait.
fn next(&self) -> Option<Next> {
let sync = self.sync.lock().unwrap_or_else(|p| p.into_inner());
let ledger = sync.ledger();
let ledger = self.ledger.lock().unwrap_or_else(|p| p.into_inner());
ledger.outbox().into_iter().find_map(|(item, action)| {
let Item::Turn { session, turn } = &item else {
return None;
@@ -304,13 +313,7 @@ impl Worker {
/// Read the turn again, make sure of its Honcho session, and add its messages as one batch.
fn send(&mut self, next: &Next) -> Result<Vec<String>, Unsent> {
let sessions = self
.sync
.lock()
.unwrap_or_else(|p| p.into_inner())
.sessions()
.to_path_buf();
let (text, reply) = read_turn(&log_path(&sessions, &next.session), next.turn)
let (text, reply) = read_turn(&log_path(&self.sessions, &next.session), next.turn)
.ok_or(Unsent::Local("log"))?;
let honcho = next.honcho.as_ref().ok_or(Unsent::Local("log"))?;
let messages = batch(
@@ -367,7 +370,7 @@ impl Worker {
/// would be repeated at every step.
fn record(&mut self, record: Record) -> Step {
let result = self
.sync
.ledger
.lock()
.unwrap_or_else(|p| p.into_inner())
.append(record);
@@ -394,6 +397,19 @@ pub struct Opened {
pub sync: Arc<Mutex<TurnSync>>,
clients: Clients,
agent: String,
owner: String,
}
impl Opened {
/// The memory writes' side of the ledger (task 12).
pub fn mirror(&self) -> Mirror {
let ledger = self
.sync
.lock()
.unwrap_or_else(|p| p.into_inner())
.shared_ledger();
Mirror::new(ledger, &self.agent, &self.owner)
}
}
/// Open the ledger (a cut-off last line is logged), resume the waiting sessions, and build the
@@ -419,6 +435,7 @@ pub fn open(config: &Config, honcho: &HonchoConfig, log: &Log) -> Result<Opened,
sync: Arc::new(Mutex::new(sync)),
clients,
agent: honcho.agent.clone(),
owner: honcho.owner.clone(),
})
}