* feat: Implement DNS management for macOS
- Added `set_public_dns` and `restore_public_dns` functions in `dns.rs` to manage system DNS settings.
- Introduced `resolve` module to encapsulate DNS and scheme resolution functionalities.
- Implemented `resolve_scheme` function in `scheme.rs` to handle deep links and profile imports.
- Created UI readiness management in `ui.rs` to track and update UI loading states.
- Developed window management logic in `window.rs` to handle window creation and visibility.
- Added initial loading overlay script in `window_script.rs` for better user experience during startup.
- Updated server handling in `server.rs` to integrate new resolve functionalities.
- Refactored window creation calls in `window_manager.rs` to use the new window management logic.
* refactor: streamline asynchronous handling in config and resolve setup
* Revert "refactor: streamline asynchronous handling in config and resolve setup"
This reverts commit 23d7dc86d5.
* fix: optimize asynchronous memory handling
* fix: enhance task logging by adding size check for special cases
* refactor: enhance async initialization and streamline setup process
* refactor: optimize async setup by consolidating initialization tasks
* chore: update changelog for Mihomo(Meta) kernel upgrade to v1.19.13
* fix: improve startup phase initialization performance
* refactor: optimize file read/write performance to reduce application wait time
* refactor: simplify app instance exit logic and adjust system proxy guard initialization
* refactor: change resolve_setup_async to synchronous execution for improved performance
* refactor: update resolve_setup_async to accept AppHandle for improved initialization flow
* refactor: remove unnecessary initialization of portable flag in run function
* refactor: consolidate async initialization tasks into a single blocking call for improved execution flow
* refactor: optimize resolve_setup_async by restructuring async tasks for improved concurrency
* refactor: streamline resolve_setup_async and embed_server for improved async handling
* refactor: separate synchronous and asynchronous setup functions for improved clarity
* refactor: simplify async notification handling and remove redundant network manager initialization
* refactor: enhance async handling in proxy request cache and window creation logic
* refactor: improve code formatting and readability in ProxyRequestCache
* refactor: adjust singleton check timeout and optimize trace size conditions
* refactor: update TRACE_SPECIAL_SIZE to include additional size condition
* refactor: update kode-bridge dependency to version 0.2.1-rc2
* refactor: replace RwLock with AtomicBool for UI readiness and implement event-driven monitoring
* refactor: convert async functions to synchronous for window management
* Update src-tauri/src/utils/resolve/window.rs
* fix: handle missing app_handle in create_window function
* Update src-tauri/src/module/lightweight.rs
85 lines
2.5 KiB
Rust
85 lines
2.5 KiB
Rust
use crate::singleton;
|
|
use dashmap::DashMap;
|
|
use serde_json::Value;
|
|
use std::sync::Arc;
|
|
use std::time::{Duration, Instant};
|
|
use tokio::sync::OnceCell;
|
|
|
|
pub struct CacheEntry {
|
|
pub value: Arc<Value>,
|
|
pub expires_at: Instant,
|
|
}
|
|
|
|
pub struct ProxyRequestCache {
|
|
pub map: DashMap<String, Arc<OnceCell<CacheEntry>>>,
|
|
}
|
|
|
|
impl ProxyRequestCache {
|
|
fn new() -> Self {
|
|
ProxyRequestCache {
|
|
map: DashMap::new(),
|
|
}
|
|
}
|
|
|
|
pub fn make_key(prefix: &str, id: &str) -> String {
|
|
format!("{prefix}:{id}")
|
|
}
|
|
|
|
pub async fn get_or_fetch<F, Fut>(&self, key: String, ttl: Duration, fetch_fn: F) -> Arc<Value>
|
|
where
|
|
F: Fn() -> Fut + Send + 'static,
|
|
Fut: std::future::Future<Output = Value> + Send + 'static,
|
|
{
|
|
loop {
|
|
let now = Instant::now();
|
|
let key_cloned = key.clone();
|
|
|
|
// Get or create the cell
|
|
let cell = self
|
|
.map
|
|
.entry(key_cloned.clone())
|
|
.or_insert_with(|| Arc::new(OnceCell::new()))
|
|
.clone();
|
|
|
|
// Check if we have a valid cached entry
|
|
if let Some(entry) = cell.get() {
|
|
if entry.expires_at > now {
|
|
return Arc::clone(&entry.value);
|
|
}
|
|
// Entry is expired, remove it
|
|
self.map
|
|
.remove_if(&key_cloned, |_, v| Arc::ptr_eq(v, &cell));
|
|
continue; // Retry with fresh cell
|
|
}
|
|
|
|
// Try to set a new value
|
|
let value = fetch_fn().await;
|
|
let entry = CacheEntry {
|
|
value: Arc::new(value),
|
|
expires_at: Instant::now() + ttl,
|
|
};
|
|
|
|
match cell.set(entry) {
|
|
Ok(_) => {
|
|
// Successfully set the value, it must exist now
|
|
if let Some(set_entry) = cell.get() {
|
|
return Arc::clone(&set_entry.value);
|
|
}
|
|
}
|
|
Err(_) => {
|
|
if let Some(existing_entry) = cell.get() {
|
|
if existing_entry.expires_at > Instant::now() {
|
|
return Arc::clone(&existing_entry.value);
|
|
}
|
|
self.map
|
|
.remove_if(&key_cloned, |_, v| Arc::ptr_eq(v, &cell));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Use singleton macro
|
|
singleton!(ProxyRequestCache, INSTANCE);
|