memoryd: the Honcho worker sends decided turns, waits out outages, retries undecided turns

Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
2026-09-28 12:30:49 -07:00
co-authored by ornith-1.5-35b-a3b
parent aabfbc2f0a
commit b37eaef390
12 changed files with 1451 additions and 34 deletions
+26 -25
View File
@@ -16,9 +16,10 @@ use bxcore::{
use crate::config::Config;
use crate::edit::{self, Context};
use crate::files::Store;
use crate::honcho::ledger::{self, Ledger, LedgerError};
use crate::honcho::ledger::{self, LedgerError};
use crate::honcho::state;
use crate::honcho::turns::{self, TurnSync};
use crate::honcho::turns::TurnSync;
use crate::honcho::worker::{self, Wake};
use crate::index::{self, Index};
use crate::recall::Recalled;
use crate::{journal, recall, review};
@@ -39,7 +40,9 @@ pub struct Memoryd {
state: Mutex<State>,
/// With `[honcho]`: the turns reported and not yet decided, and the ledger. Never taken
/// while `state` is held, and never held by a request that waits for its answer.
honcho: Option<Mutex<TurnSync>>,
honcho: Option<Arc<Mutex<TurnSync>>>,
/// Wakes the Honcho worker when a turn has been decided.
wake: Arc<Wake>,
log: Log,
}
@@ -49,12 +52,14 @@ pub struct Memoryd {
pub enum StartError {
Failed(String),
Ledger(LedgerError),
/// A Honcho key that cannot be read: `bxcore::secrets`' line, with its own pointer.
Secret(String),
}
impl std::fmt::Display for StartError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StartError::Failed(why) => write!(f, "{why}"),
StartError::Failed(why) | StartError::Secret(why) => write!(f, "{why}"),
// `Damaged` names its pointer itself.
StartError::Ledger(e @ LedgerError::Damaged { .. }) => write!(f, "{e}"),
StartError::Ledger(e) => write!(f, "{e}; {}", ledger::RUNBOOK),
@@ -83,28 +88,12 @@ enum Which {
Admin,
}
/// With `[honcho]`, read the ledger through first. Then create what is missing under `memory/`,
/// open the index and catch it up, and bind the three sockets. The error names what failed.
/// With `[honcho]`, read the ledger through and the keys first. Then create what is missing
/// under `memory/`, open the index and catch it up, bind the three sockets, and start the Honcho
/// worker. The error names what failed.
pub fn start(config: Config, log: Log) -> Result<Running, StartError> {
let honcho = match config.honcho_config()? {
Some(honcho) => {
let path = config.memory_dir().join(turns::LEDGER);
let ledger = Ledger::open(&path).map_err(StartError::Ledger)?;
if ledger.repaired() {
(log)(
format!(
"memoryd: {}: a last line cut off by a crash was dropped",
path.display()
)
.as_str(),
);
}
Some(Mutex::new(TurnSync::new(
ledger,
&honcho.agent,
&config.sessions_dir(),
)))
}
let opened = match config.honcho_config()? {
Some(honcho) => Some(worker::open(&config, &honcho, &log)?),
None => None,
};
let store = Store::new(&config.memory_dir());
@@ -122,12 +111,22 @@ pub fn start(config: Config, log: Log) -> Result<Running, StartError> {
(broker_listener, Which::Broker),
(admin_listener, Which::Admin),
];
let wake = Arc::new(Wake::default());
let honcho = match opened {
Some(opened) => {
let sync = Arc::clone(&opened.sync);
worker::spawn(opened, &config, Arc::clone(&wake), Arc::clone(&log))?;
Some(sync)
}
None => None,
};
Ok(Running {
memoryd: Arc::new(Memoryd {
config,
store,
state: Mutex::new(State { index }),
honcho,
wake,
log,
}),
listeners,
@@ -233,6 +232,8 @@ impl Memoryd {
Timestamp::now(),
&*self.log,
);
drop(sync);
self.wake.notify();
}
/// The answer to one request on one socket. A message sent to the wrong socket is refused.