rsclaw 0.0.1-alpha.1

rsclaw: High-performance AI agent (BETA). Optimized for M4 Max and 2GB VPS. 100% compatible with openclaw
Documentation
use super::executor::ExecutionResult;
use super::store::CronStore;
use super::types::{CronTask, TaskStatus};
use anyhow::Result;
use std::sync::Arc;

/// Task monitor for logging and retry.
pub struct TaskMonitor {
    store: Arc<CronStore>,
}

impl TaskMonitor {
    /// Create a new task monitor.
    pub fn new(store: Arc<CronStore>) -> Self {
        Self { store }
    }

    /// Record task execution result.
    pub fn record_execution(&self, task: &mut CronTask, result: &ExecutionResult) -> Result<()> {
        let now = std::time::SystemTime::now()
            .duration_since(std::time::SystemTime::UNIX_EPOCH)?
            .as_secs();

        task.last_run = Some(now);

        if result.success {
            task.status = TaskStatus::Completed;
            task.retry_count = 0;
            task.last_error = None;
            tracing::info!(
                "Task '{}' completed in {}ms: {}",
                task.id,
                result.duration_ms,
                result.output
            );
        } else {
            task.retry_count += 1;
            task.last_error = result.error.clone();

            if task.retry_count >= task.max_retries {
                task.status = TaskStatus::Failed;
                tracing::error!(
                    "Task '{}' failed after {} retries: {}",
                    task.id,
                    task.retry_count,
                    result.error.as_deref().unwrap_or("unknown")
                );
            } else {
                task.status = TaskStatus::Pending;
                tracing::warn!(
                    "Task '{}' failed (attempt {}/{}): {}",
                    task.id,
                    task.retry_count,
                    task.max_retries,
                    result.error.as_deref().unwrap_or("unknown")
                );
            }
        }

        self.store.save(task)?;
        Ok(())
    }

    /// Get failed tasks.
    pub fn get_failed_tasks(&self) -> Result<Vec<CronTask>> {
        let tasks = self.store.list_all()?;
        Ok(tasks
            .into_iter()
            .filter(|t| t.status == TaskStatus::Failed)
            .collect())
    }

    /// Reset a failed task for retry.
    pub fn reset_task(&self, task_id: &str) -> Result<bool> {
        if let Some(mut task) = self.store.load(task_id)? {
            task.status = TaskStatus::Pending;
            task.retry_count = 0;
            task.last_error = None;
            self.store.save(&task)?;
            Ok(true)
        } else {
            Ok(false)
        }
    }
}