monothink 0.6.0

A totally non-agentic coding assistant
/*
* This file is part of monothink.
*
* monothink is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* monothink is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with monothink.
* If not, see <https://www.gnu.org/licenses/>.

*/

use std::sync::Arc;
use tokio::sync::{Mutex, mpsc::Sender as TokioSender};

// sender does not require to check and handle result at sending site
// instead it sets a fail state that each actor can handle centrally
// this makes sense for this application as the actors are stable and
// a closed channel should not occur.
// note that wiring down the application is handle almost like a unwrap with only some log messages.
// Rationale is as above that this should not occur in practice.
#[derive(Debug, Clone)]
pub struct Sender<T> {
    tx: TokioSender<T>,
    channel_closed: Arc<Mutex<bool>>,
}

impl<T> Sender<T> {
    pub fn new(tx: TokioSender<T>) -> Sender<T> {
        Self {
            tx,
            channel_closed: Arc::new(Mutex::new(false)),
        }
    }

    pub async fn send(&self, msg: T) {
        match self.tx.send(msg).await {
            Ok(_) => {}
            Err(e) => {
                tracing::error!(
                    error = e.to_string(),
                    "Cannot send message to session. Terminating Llm actor."
                );
                *self.channel_closed.lock().await = true;
            }
        }
    }

    pub async fn closed(&self) -> bool {
        *self.channel_closed.lock().await
    }
}