diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-06-13 00:50:54 +0200 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-06-13 00:50:54 +0200 |
| commit | 6723829a3398b3c9dd6dc6ae79124f46000606ee (patch) | |
| tree | a1ec535eddd711a4557e4bcc5b94382c3623504c /crates/turtle/src/atuin_daemon/components | |
| parent | chore(treewide): Cleanup themes (diff) | |
| download | atuin-6723829a3398b3c9dd6dc6ae79124f46000606ee.zip | |
chore(treewide): Remove `cargo` warnings to 0
There are still the `clippy` warnings, but they are for a future date.
Diffstat (limited to 'crates/turtle/src/atuin_daemon/components')
4 files changed, 63 insertions, 49 deletions
diff --git a/crates/turtle/src/atuin_daemon/components/history.rs b/crates/turtle/src/atuin_daemon/components/history.rs index b71543c1..b4f91b06 100644 --- a/crates/turtle/src/atuin_daemon/components/history.rs +++ b/crates/turtle/src/atuin_daemon/components/history.rs @@ -18,7 +18,7 @@ use tracing::{Level, instrument}; use crate::atuin_daemon::{ daemon::{Component, DaemonHandle}, events::DaemonEvent, - history::{ + generated::history::{ EndHistoryReply, EndHistoryRequest, HistoryEntry, HistoryEventKind, ShutdownReply, ShutdownRequest, StartHistoryReply, StartHistoryRequest, StatusReply, StatusRequest, TailHistoryReply, TailHistoryRequest, @@ -144,8 +144,8 @@ impl HistorySvc for HistoryGrpcService { ) -> Result<Response<StartHistoryReply>, Status> { let req = request.into_inner(); - let timestamp = - OffsetDateTime::from_unix_timestamp_nanos(req.timestamp as i128).map_err(|_| { + let timestamp = OffsetDateTime::from_unix_timestamp_nanos(i128::from(req.timestamp)) + .map_err(|_| { Status::invalid_argument( "failed to parse timestamp as unix time (expected nanos since epoch)", ) @@ -181,6 +181,7 @@ impl HistorySvc for HistoryGrpcService { } #[instrument(skip_all, level = Level::INFO)] + #[expect(clippy::significant_drop_tightening, reason = "Would be a logic-bug")] async fn end_history( &self, request: Request<EndHistoryRequest>, @@ -216,11 +217,7 @@ impl HistorySvc for HistoryGrpcService { .await .map_err(|e| Status::internal(format!("failed to write to db: {e:?}")))?; - tracing::info!( - id = id.0.to_string(), - duration = history.duration, - "end history" - ); + tracing::info!(id = id.0, duration = history.duration, "end history"); // Push to record store let (record_id, idx) = history_store @@ -247,6 +244,7 @@ impl HistorySvc for HistoryGrpcService { } #[instrument(skip_all, level = Level::INFO)] + #[expect(clippy::significant_drop_tightening, reason = "Would be a logic-bug")] async fn tail_history( &self, _request: Request<TailHistoryRequest>, @@ -265,11 +263,12 @@ impl HistorySvc for HistoryGrpcService { let event = match rx.recv().await { Ok(event) => event, Err(tokio::sync::broadcast::error::RecvError::Lagged(skipped)) => { - let _ = tx - .send(Err(Status::resource_exhausted(format!( + drop( + tx.send(Err(Status::resource_exhausted(format!( "tail stream lagged behind and dropped {skipped} events" )))) - .await; + .await, + ); break; } Err(tokio::sync::broadcast::error::RecvError::Closed) => break, diff --git a/crates/turtle/src/atuin_daemon/components/search.rs b/crates/turtle/src/atuin_daemon/components/search.rs index 832d05d8..39df758b 100644 --- a/crates/turtle/src/atuin_daemon/components/search.rs +++ b/crates/turtle/src/atuin_daemon/components/search.rs @@ -15,10 +15,11 @@ use uuid::Uuid; use crate::atuin_daemon::{ daemon::{Component, DaemonHandle}, events::DaemonEvent, - search::{ - FilterMode, IndexFilterMode, QueryContext, SearchIndex, SearchRequest, SearchResponse, + generated::search::{ + self, FilterMode, SearchRequest, SearchResponse, search_server::{Search as SearchSvc, SearchServer}, }, + search::{IndexFilterMode, QueryContext, SearchIndex}, }; const PAGE_SIZE: usize = 5000; @@ -35,7 +36,7 @@ const FRECENCY_REFRESH_INTERVAL_SECS: u64 = 60; /// - Provides the Search gRPC service pub(crate) struct SearchComponent { index: Arc<RwLock<SearchIndex>>, - handle: tokio::sync::RwLock<Option<DaemonHandle>>, + handle: RwLock<Option<DaemonHandle>>, loader_handle: Option<tokio::task::JoinHandle<()>>, frecency_handle: Option<tokio::task::JoinHandle<()>>, } @@ -45,7 +46,7 @@ impl SearchComponent { pub(crate) fn new() -> Self { Self { index: Arc::new(RwLock::new(SearchIndex::new())), - handle: tokio::sync::RwLock::new(None), + handle: RwLock::new(None), loader_handle: None, frecency_handle: None, } @@ -351,7 +352,7 @@ impl SearchSvc for SearchGrpcService { } } Err(e) => { - let _ = tx.send(Err(e)).await; + drop(tx.send(Err(e)).await); break; } } @@ -367,7 +368,7 @@ impl SearchSvc for SearchGrpcService { /// Convert proto FilterMode and context to IndexFilterMode. fn convert_filter_mode( mode: FilterMode, - context: &Option<crate::atuin_daemon::search::SearchContext>, + context: &Option<search::SearchContext>, ) -> IndexFilterMode { match (mode, context) { (FilterMode::Global, _) => IndexFilterMode::Global, diff --git a/crates/turtle/src/atuin_daemon/components/semantic.rs b/crates/turtle/src/atuin_daemon/components/semantic.rs index 052c2d73..69ffc134 100644 --- a/crates/turtle/src/atuin_daemon/components/semantic.rs +++ b/crates/turtle/src/atuin_daemon/components/semantic.rs @@ -9,6 +9,7 @@ use std::fmt::{Display, Formatter}; use std::sync::Arc; use crate::atuin_client::history::{History, HistoryId}; +use crate::atuin_daemon::generated::semantic; use eyre::Result; use tokio::sync::Mutex; use tonic::{Request, Response, Status, Streaming}; @@ -17,7 +18,7 @@ use tracing::{Level, instrument}; use crate::atuin_daemon::{ daemon::{Component, DaemonHandle}, events::DaemonEvent, - semantic::{ + generated::semantic::{ CommandCapture, CommandOutputReply, CommandOutputRequest, OutputLine, RecordCommandsReply, semantic_server::{Semantic as SemanticSvc, SemanticServer}, }, @@ -244,7 +245,7 @@ impl SemanticState { fn command_output_for_ref( &self, capture_ref: &CaptureRef, - ranges: &[crate::atuin_daemon::semantic::OutputRange], + ranges: &[semantic::OutputRange], ) -> Option<CommandOutputReply> { let stored = self .sessions @@ -534,17 +535,14 @@ fn command_output_not_found() -> CommandOutputReply { } } -fn select_output_ranges( - output: &str, - ranges: &[crate::atuin_daemon::semantic::OutputRange], -) -> Vec<OutputLine> { +fn select_output_ranges(output: &str, ranges: &[semantic::OutputRange]) -> Vec<OutputLine> { let lines: Vec<&str> = output.lines().collect(); if lines.is_empty() { return Vec::new(); } let ranges = if ranges.is_empty() { - vec![crate::atuin_daemon::semantic::OutputRange { start: 0, end: 999 }] + vec![semantic::OutputRange { start: 0, end: 999 }] } else { ranges.to_vec() }; @@ -627,9 +625,20 @@ fn log_record(record: &SemanticCommandRecord, message: &'static str) { #[cfg(test)] mod tests { - use super::*; use time::OffsetDateTime; + use crate::{ + atuin_client::history::{History, HistoryId}, + atuin_daemon::{ + components::semantic::{ + MAX_COMMANDS_PER_SESSION, MAX_SESSIONS, SemanticCommandRecord, SemanticState, + SessionCaptures, SessionId, select_output_ranges, + }, + generated::semantic::{self, CommandOutputReply, CommandOutputRequest, OutputLine}, + }, + atuin_pty_proxy::CommandCapture, + }; + fn history(id: &str, session: &str, command: &str) -> History { History { id: HistoryId(id.to_string()), @@ -819,8 +828,8 @@ mod tests { fn output_ranges_are_line_based_inclusive_and_support_negative_offsets() { let output = "zero\none\ntwo\nthree\nfour"; let ranges = vec![ - crate::atuin_daemon::semantic::OutputRange { start: 1, end: 2 }, - crate::atuin_daemon::semantic::OutputRange { start: -2, end: -1 }, + semantic::OutputRange { start: 1, end: 2 }, + semantic::OutputRange { start: -2, end: -1 }, ]; assert_eq!( @@ -841,8 +850,8 @@ mod tests { .collect::<Vec<_>>() .join("\n"); let ranges = vec![ - crate::atuin_daemon::semantic::OutputRange { start: 0, end: 100 }, - crate::atuin_daemon::semantic::OutputRange { + semantic::OutputRange { start: 0, end: 100 }, + semantic::OutputRange { start: -100, end: -1, }, @@ -859,8 +868,8 @@ mod tests { fn output_ranges_can_leave_gaps_for_client_formatting() { let output = "zero\none\ntwo\nthree\nfour"; let ranges = vec![ - crate::atuin_daemon::semantic::OutputRange { start: 0, end: 1 }, - crate::atuin_daemon::semantic::OutputRange { start: 4, end: 4 }, + semantic::OutputRange { start: 0, end: 1 }, + semantic::OutputRange { start: 4, end: 4 }, ]; assert_eq!( @@ -891,8 +900,8 @@ mod tests { fn output_ranges_skip_ranges_fully_outside_output() { let output = "zero\none\ntwo"; let ranges = vec![ - crate::atuin_daemon::semantic::OutputRange { start: 10, end: 20 }, - crate::atuin_daemon::semantic::OutputRange { + semantic::OutputRange { start: 10, end: 20 }, + semantic::OutputRange { start: -20, end: -10, }, diff --git a/crates/turtle/src/atuin_daemon/components/sync.rs b/crates/turtle/src/atuin_daemon/components/sync.rs index fbfbbd67..8b5b621d 100644 --- a/crates/turtle/src/atuin_daemon/components/sync.rs +++ b/crates/turtle/src/atuin_daemon/components/sync.rs @@ -27,9 +27,9 @@ enum SyncCommand { /// Sync state - tracks whether we're in normal operation or retrying after failure. #[derive(Clone, Copy, PartialEq, Eq)] enum SyncState { - /// Normal operation. Periodic syncs only run if auto_sync is enabled. + /// Normal operation. Periodic syncs only run if [`auto_sync`] is enabled. Idle, - /// Retrying after a sync failure. Retries continue regardless of auto_sync + /// Retrying after a sync failure. Retries continue regardless of [`auto_sync`] /// until the sync succeeds. Retrying, } @@ -39,7 +39,7 @@ enum SyncState { /// This component: /// - Runs a background sync loop on a configurable interval /// - Implements exponential backoff on sync failures -/// - Responds to ForceSync events for immediate sync +/// - Responds to [`ForceSync`] events for immediate sync /// - Emits SyncCompleted/SyncFailed events pub(crate) struct SyncComponent { task_handle: Option<tokio::task::JoinHandle<()>>, @@ -80,22 +80,28 @@ impl Component for SyncComponent { } async fn handle_event(&mut self, event: &DaemonEvent) -> Result<()> { - if let DaemonEvent::ForceSync = event { - tracing::info!("force sync requested"); - if let Some(tx) = &self.command_tx { - let _ = tx.send(SyncCommand::ForceSync).await; + match event { + DaemonEvent::ForceSync => { + tracing::info!("force sync requested"); + if let Some(tx) = &self.command_tx { + drop(tx.send(SyncCommand::ForceSync).await); + } + } + DaemonEvent::SyncFailed { error } => { + tracing::error!(?error, "Sync failed."); } + _ => (), } Ok(()) } async fn stop(&mut self) -> Result<()> { if let Some(tx) = &self.command_tx { - let _ = tx.send(SyncCommand::Stop).await; + drop(tx.send(SyncCommand::Stop).await); } if let Some(handle) = self.task_handle.take() { // Give the task a moment to shut down gracefully - let _ = tokio::time::timeout(std::time::Duration::from_secs(5), handle).await; + drop(time::timeout(Duration::from_secs(5), handle).await); } tracing::info!("sync component stopped"); Ok(()) @@ -126,7 +132,7 @@ async fn sync_loop(handle: DaemonHandle, mut cmd_rx: mpsc::Receiver<SyncCommand> // Don't backoff by more than 30 mins (with a random jitter of up to 1 min) let max_interval: f64 = 60.0 * 30.0 + rand::thread_rng().gen_range(0.0..60.0); - let mut ticker = time::interval(time::Duration::from_secs(settings.daemon.sync_frequency)); + let mut ticker = time::interval(Duration::from_secs(settings.daemon.sync_frequency)); // IMPORTANT: without this, if we miss ticks because a sync takes ages or is otherwise delayed, // we may end up running a lot of syncs in a hot loop. @@ -224,10 +230,10 @@ async fn do_sync_tick( } *ticker = time::interval_at( - tokio::time::Instant::now() + Duration::from_secs(new_interval as u64), - time::Duration::from_secs(new_interval as u64), + time::Instant::now() + Duration::from_secs(new_interval as u64), + Duration::from_secs(new_interval as u64), ); - ticker.reset_after(time::Duration::from_secs(new_interval as u64)); + ticker.reset_after(Duration::from_secs(new_interval as u64)); ticker.set_missed_tick_behavior(MissedTickBehavior::Skip); tracing::error!("backing off, next sync tick in {new_interval}"); @@ -261,9 +267,8 @@ async fn do_sync_tick( // Reset backoff on success if ticker.period().as_secs() != settings.daemon.sync_frequency { *ticker = time::interval_at( - tokio::time::Instant::now() - + Duration::from_secs(settings.daemon.sync_frequency), - time::Duration::from_secs(settings.daemon.sync_frequency), + time::Instant::now() + Duration::from_secs(settings.daemon.sync_frequency), + Duration::from_secs(settings.daemon.sync_frequency), ); ticker.set_missed_tick_behavior(MissedTickBehavior::Skip); } |
