From bf1d17ad7dd4707e6f41e83a145c145bab727cf5 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Sat, 14 Aug 2021 11:43:23 +0200 Subject: [PATCH] feat(core): cache app info provider results --- .../worker/engine/caches/app_info_provider.rs | 56 +++++++++++++++++++ espanso/src/cli/worker/engine/caches/mod.rs | 20 +++++++ espanso/src/cli/worker/engine/mod.rs | 7 ++- 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 espanso/src/cli/worker/engine/caches/app_info_provider.rs create mode 100644 espanso/src/cli/worker/engine/caches/mod.rs diff --git a/espanso/src/cli/worker/engine/caches/app_info_provider.rs b/espanso/src/cli/worker/engine/caches/app_info_provider.rs new file mode 100644 index 0000000..6b03863 --- /dev/null +++ b/espanso/src/cli/worker/engine/caches/app_info_provider.rs @@ -0,0 +1,56 @@ +/* + * This file is part of espanso. + * + * Copyright (C) 2019-2021 Federico Terzi + * + * espanso 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. + * + * espanso 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 espanso. If not, see . + */ + +use std::{cell::RefCell, time::{Duration, Instant}}; + +use espanso_info::{AppInfo, AppInfoProvider}; + +pub struct CachedAppInfoProvider<'a> { + app_info_provider: &'a dyn AppInfoProvider, + caching_interval: Duration, + + _cached_info: RefCell>, +} + +impl<'a> CachedAppInfoProvider<'a> { + pub fn from(app_info_provider: &'a dyn AppInfoProvider, caching_interval: Duration) -> Self { + Self { + app_info_provider, + caching_interval, + _cached_info: RefCell::new(None), + } + } +} + +impl<'a> AppInfoProvider for CachedAppInfoProvider<'a> { + fn get_info(&self) -> espanso_info::AppInfo { + let mut cached_info = self._cached_info.borrow_mut(); + if let Some((instant, cached_value)) = &*cached_info { + if instant.elapsed() < self.caching_interval { + // Return cached config + return cached_value.clone(); + } + } + + let info = self.app_info_provider.get_info(); + *cached_info = Some((Instant::now(), info.clone())); + + info + } +} diff --git a/espanso/src/cli/worker/engine/caches/mod.rs b/espanso/src/cli/worker/engine/caches/mod.rs new file mode 100644 index 0000000..d5f2e9d --- /dev/null +++ b/espanso/src/cli/worker/engine/caches/mod.rs @@ -0,0 +1,20 @@ +/* + * This file is part of espanso. + * + * Copyright (C) 2019-2021 Federico Terzi + * + * espanso 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. + * + * espanso 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 espanso. If not, see . + */ + +pub mod app_info_provider; \ No newline at end of file diff --git a/espanso/src/cli/worker/engine/mod.rs b/espanso/src/cli/worker/engine/mod.rs index 105ea91..669f94c 100644 --- a/espanso/src/cli/worker/engine/mod.rs +++ b/espanso/src/cli/worker/engine/mod.rs @@ -49,6 +49,7 @@ use super::secure_input::SecureInputEvent; pub mod dispatch; pub mod funnel; pub mod process; +mod caches; mod keyboard_layout_util; #[allow(clippy::too_many_arguments)] @@ -71,15 +72,17 @@ pub fn initialize_and_spawn( let app_info_provider = espanso_info::get_provider().expect("unable to initialize app info provider"); + // TODO: read interval from configs? + let cached_app_info_provider = caches::app_info_provider::CachedAppInfoProvider::from(&*app_info_provider, std::time::Duration::from_millis(400)); let config_manager = - super::config::ConfigManager::new(&*config_store, &*match_store, &*app_info_provider); + super::config::ConfigManager::new(&*config_store, &*match_store, &cached_app_info_provider); let match_cache = MatchCache::load(&*config_store, &*match_store); let modulo_manager = crate::gui::modulo::manager::ModuloManager::new(); let modulo_form_ui = crate::gui::modulo::form::ModuloFormUI::new(&modulo_manager); let modulo_search_ui = crate::gui::modulo::search::ModuloSearchUI::new(&modulo_manager); - let context: Box = Box::new(super::context::DefaultContext::new(&config_manager, &*app_info_provider)); + let context: Box = Box::new(super::context::DefaultContext::new(&config_manager, &cached_app_info_provider)); let builtin_matches = super::builtin::get_builtin_matches(&*config_manager.default()); let combined_match_cache = CombinedMatchCache::load(&match_cache, &builtin_matches);