clawft_kernel/
talk_loop_service.rs1use std::sync::Arc;
7
8use async_trait::async_trait;
9
10use super::TalkModeLoop;
11use crate::health::HealthStatus;
12use crate::service::{ServiceType, SystemService};
13
14#[async_trait]
15impl SystemService for TalkModeLoop {
16 fn name(&self) -> &str {
17 "voice.talk_mode"
18 }
19
20 fn service_type(&self) -> ServiceType {
21 ServiceType::Core
22 }
23
24 async fn start(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
25 self.tick.set_running(true);
26 Ok(())
27 }
28
29 async fn stop(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
30 self.tick.set_running(false);
31 Ok(())
32 }
33
34 async fn health_check(&self) -> HealthStatus {
35 if self.tick.is_running() {
36 HealthStatus::Healthy
37 } else {
38 HealthStatus::Degraded("talk-mode tick not running".into())
39 }
40 }
41}
42
43#[cfg(feature = "native")]
48pub async fn run_talk_loop(loop_: Arc<TalkModeLoop>, cancel: tokio_util::sync::CancellationToken) {
49 loop_.tick.set_running(true);
50 tracing::info!("Talk-Mode loop started");
51 loop {
52 let interval_ms = loop_.tick.current_interval_ms();
53 if interval_ms == 0 {
54 tracing::warn!("Talk-Mode loop: tick interval is 0, exiting");
55 break;
56 }
57 tokio::select! {
58 _ = cancel.cancelled() => break,
59 _ = tokio::time::sleep(tokio::time::Duration::from_millis(interval_ms as u64)) => {}
60 }
61 if !loop_.tick.is_running() {
62 break;
63 }
64 loop_.tick();
65 }
66 loop_.tick.set_running(false);
67 tracing::info!("Talk-Mode loop exited");
68}