mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 19:45:23 +00:00
working on channel shutdown and caching strategies
This commit is contained in:
parent
5556515240
commit
9d6d1f47ba
@ -1,6 +1,6 @@
|
||||
use crate::entry::Entry;
|
||||
use color_eyre::eyre::Result;
|
||||
use television_derive::{CliChannel, Broadcast, UnitChannel};
|
||||
use television_derive::{Broadcast, CliChannel, UnitChannel};
|
||||
|
||||
mod alias;
|
||||
pub mod channels;
|
||||
@ -70,7 +70,7 @@ pub trait OnAir: Send {
|
||||
|
||||
/// Check if the channel is currently running.
|
||||
fn running(&self) -> bool;
|
||||
|
||||
|
||||
/// Turn off
|
||||
fn shutdown(&self);
|
||||
}
|
||||
|
@ -199,9 +199,7 @@ impl OnAir for Channel {
|
||||
self.running
|
||||
}
|
||||
|
||||
fn shutdown(&self) {
|
||||
todo!()
|
||||
}
|
||||
fn shutdown(&self) {}
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_async)]
|
||||
|
@ -134,7 +134,5 @@ impl OnAir for SelectionChannel {
|
||||
self.running
|
||||
}
|
||||
|
||||
fn shutdown(&self) {
|
||||
todo!()
|
||||
}
|
||||
fn shutdown(&self) {}
|
||||
}
|
||||
|
@ -161,7 +161,5 @@ impl OnAir for Channel {
|
||||
self.running
|
||||
}
|
||||
|
||||
fn shutdown(&self) {
|
||||
todo!()
|
||||
}
|
||||
fn shutdown(&self) {}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ pub struct Channel {
|
||||
result_count: u32,
|
||||
total_count: u32,
|
||||
running: bool,
|
||||
crawl_handle: tokio::task::JoinHandle<()>,
|
||||
// PERF: cache results (to make deleting characters smoother) but like
|
||||
// a shallow cache (maybe more like a stack actually? so we just pop result sets)
|
||||
}
|
||||
@ -38,7 +39,7 @@ impl Channel {
|
||||
1,
|
||||
);
|
||||
// start loading files in the background
|
||||
tokio::spawn(load_files(
|
||||
let crawl_handle = tokio::spawn(load_files(
|
||||
starting_dir.to_path_buf(),
|
||||
matcher.injector(),
|
||||
));
|
||||
@ -48,6 +49,7 @@ impl Channel {
|
||||
result_count: 0,
|
||||
total_count: 0,
|
||||
running: false,
|
||||
crawl_handle,
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +135,7 @@ impl OnAir for Channel {
|
||||
}
|
||||
|
||||
fn shutdown(&self) {
|
||||
todo!()
|
||||
self.crawl_handle.abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
use std::sync::Arc;
|
||||
use color_eyre::owo_colors::OwoColorize;
|
||||
use devicons::FileIcon;
|
||||
use ignore::{overrides::OverrideBuilder, DirEntry};
|
||||
@ -6,7 +5,12 @@ use nucleo::{
|
||||
pattern::{CaseMatching, Normalization},
|
||||
Config, Nucleo,
|
||||
};
|
||||
use tokio::sync::{oneshot, watch};
|
||||
use parking_lot::Mutex;
|
||||
use std::{collections::HashSet, sync::Arc};
|
||||
use tokio::{
|
||||
sync::{oneshot, watch},
|
||||
task::JoinHandle,
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::{
|
||||
@ -25,7 +29,10 @@ pub struct Channel {
|
||||
total_count: u32,
|
||||
running: bool,
|
||||
icon: FileIcon,
|
||||
crawl_cancellation_tx: watch::Sender<bool>,
|
||||
crawl_handle: JoinHandle<()>,
|
||||
entry_cache: Arc<Mutex<HashSet<String>>>,
|
||||
// TODO: implement cache validation/invalidation
|
||||
cache_valid: bool,
|
||||
}
|
||||
|
||||
impl Channel {
|
||||
@ -36,12 +43,13 @@ impl Channel {
|
||||
None,
|
||||
1,
|
||||
);
|
||||
let entry_cache = Arc::new(Mutex::new(HashSet::new()));
|
||||
// start loading files in the background
|
||||
let (tx, rx) = watch::channel(false);
|
||||
tokio::spawn(crawl_for_repos(
|
||||
// PERF: store the results somewhere in a cache
|
||||
let crawl_handle = tokio::spawn(crawl_for_repos(
|
||||
std::env::home_dir().expect("Could not get home directory"),
|
||||
matcher.injector(),
|
||||
rx,
|
||||
entry_cache.clone(),
|
||||
));
|
||||
Channel {
|
||||
matcher,
|
||||
@ -50,7 +58,9 @@ impl Channel {
|
||||
total_count: 0,
|
||||
running: false,
|
||||
icon: FileIcon::from("git"),
|
||||
crawl_cancellation_tx: tx,
|
||||
crawl_handle,
|
||||
entry_cache,
|
||||
cache_valid: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +147,8 @@ impl OnAir for Channel {
|
||||
}
|
||||
|
||||
fn shutdown(&self) {
|
||||
self.crawl_cancellation_tx.send(true).unwrap();
|
||||
debug!("Shutting down git repos channel");
|
||||
self.crawl_handle.abort();
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +156,7 @@ impl OnAir for Channel {
|
||||
async fn crawl_for_repos(
|
||||
starting_point: std::path::PathBuf,
|
||||
injector: nucleo::Injector<DirEntry>,
|
||||
cancellation_rx: watch::Receiver<bool>,
|
||||
entry_cache: Arc<Mutex<HashSet<String>>>,
|
||||
) {
|
||||
let mut walker_overrides_builder = OverrideBuilder::new(&starting_point);
|
||||
walker_overrides_builder.add(".git").unwrap();
|
||||
@ -158,25 +169,31 @@ async fn crawl_for_repos(
|
||||
|
||||
walker.run(|| {
|
||||
let injector = injector.clone();
|
||||
let cancellation_rx = cancellation_rx.clone();
|
||||
let entry_cache = entry_cache.clone();
|
||||
Box::new(move |result| {
|
||||
if let Ok(true) = cancellation_rx.has_changed() {
|
||||
debug!("Crawling for git repos cancelled");
|
||||
return ignore::WalkState::Quit;
|
||||
}
|
||||
if let Ok(entry) = result {
|
||||
if entry.file_type().unwrap().is_dir()
|
||||
&& entry.path().ends_with(".git")
|
||||
{
|
||||
debug!("Found git repo: {:?}", entry.path());
|
||||
let _ = injector.push(entry, |e, cols| {
|
||||
cols[0] = e
|
||||
if entry.file_type().unwrap().is_dir() {
|
||||
// if the dir is already in cache, skip it
|
||||
let path = entry.path().to_string_lossy().to_string();
|
||||
if entry_cache.lock().contains(&path) {
|
||||
return ignore::WalkState::Skip;
|
||||
}
|
||||
// if the entry is a .git directory, add its parent to the list
|
||||
// of git repos and cache it
|
||||
if entry.path().ends_with(".git") {
|
||||
let parent_path = entry
|
||||
.path()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.into();
|
||||
});
|
||||
.to_string();
|
||||
debug!("Found git repo: {:?}", parent_path);
|
||||
let _ = injector.push(entry, |_e, cols| {
|
||||
cols[0] = parent_path.clone().into();
|
||||
});
|
||||
entry_cache.lock().insert(parent_path);
|
||||
return ignore::WalkState::Skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
ignore::WalkState::Continue
|
||||
|
@ -150,7 +150,5 @@ impl OnAir for Channel {
|
||||
self.running
|
||||
}
|
||||
|
||||
fn shutdown(&self) {
|
||||
todo!()
|
||||
}
|
||||
fn shutdown(&self) {}
|
||||
}
|
||||
|
@ -47,13 +47,14 @@ pub struct Channel {
|
||||
result_count: u32,
|
||||
total_count: u32,
|
||||
running: bool,
|
||||
crawl_handle: tokio::task::JoinHandle<()>,
|
||||
}
|
||||
|
||||
impl Channel {
|
||||
pub fn new(working_dir: &Path) -> Self {
|
||||
let matcher = Nucleo::new(Config::DEFAULT, Arc::new(|| {}), None, 1);
|
||||
// start loading files in the background
|
||||
tokio::spawn(load_candidates(
|
||||
let crawl_handle = tokio::spawn(load_candidates(
|
||||
working_dir.to_path_buf(),
|
||||
matcher.injector(),
|
||||
));
|
||||
@ -63,6 +64,7 @@ impl Channel {
|
||||
result_count: 0,
|
||||
total_count: 0,
|
||||
running: false,
|
||||
crawl_handle,
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +162,7 @@ impl OnAir for Channel {
|
||||
}
|
||||
|
||||
fn shutdown(&self) {
|
||||
todo!()
|
||||
self.crawl_handle.abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,13 +107,18 @@ impl Television {
|
||||
self.reset_results_selection();
|
||||
self.current_pattern = EMPTY_STRING.to_string();
|
||||
self.input.reset();
|
||||
self.channel.shutdown();
|
||||
self.channel = channel;
|
||||
}
|
||||
|
||||
const MAX_BACKUP_RESULTS: u32 = 1000;
|
||||
|
||||
fn backup_current_channel(&mut self) {
|
||||
self.last_channel = Some(UnitChannel::from(&self.channel));
|
||||
self.last_channel_results =
|
||||
self.channel.results(self.channel.result_count(), 0);
|
||||
self.last_channel_results = self.channel.results(
|
||||
self.channel.result_count().min(Self::MAX_BACKUP_RESULTS),
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
fn find(&mut self, pattern: &str) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user