mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-23 08:00:45 +00:00
9ff8a85af6
* refactor: extract windmill-api into 4 subcrates (api-auth, store, api-sse, api-jobs) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: eliminate refresh_token OnceLock bridge in windmill-store Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: eliminate FromRequestParts OnceLock bridge in windmill-api-auth Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: wire subcrates into workspace and clean up unused re-exports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: resolve cargo check --all-features errors in subcrate wiring Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * sqlx * all * chore: update ee-repo-ref for warning fixes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: extract windmill-trigger crate and expand windmill-api-jobs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract windmill-trigger-kafka crate from windmill-api Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract windmill-trigger-postgres crate from windmill-api Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract windmill-trigger-websocket and windmill-trigger-mqtt crates Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract windmill-trigger-nats, sqs, gcp, and email crates Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract windmill-trigger-http crate from windmill-api Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: move token creation and permission helpers to windmill-api-auth Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract windmill-native-triggers crate from windmill-api Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * sqlx * all * refactor: extract windmill-api-embeddings crate and fix CI warnings Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: resolve type mismatch in oauth2_oss and remaining warnings Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: use correct HTTP_CLIENT config in embeddings crate (30s timeout, cert override) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * all * fix: gate oauth_refresh_ee on oauth2 feature to fix warnings Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * all --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
121 lines
3.7 KiB
Rust
121 lines
3.7 KiB
Rust
/*
|
|
* Author: Claude
|
|
* Copyright: Windmill Labs, Inc 2025
|
|
* This file and its contents are licensed under the AGPLv3 License.
|
|
* Please see the included NOTICE for copyright information and
|
|
* LICENSE-AGPL for a copy of the license.
|
|
*/
|
|
|
|
use quick_cache::sync::Cache;
|
|
use serde_json::Value;
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
/// Cache TTL for variables and resources (30seconds)
|
|
const CACHE_TTL_SECS: u64 = 30;
|
|
|
|
/// Cache entry with timestamp and value (following raw script cache pattern)
|
|
#[derive(Clone, Debug)]
|
|
pub struct CacheEntry<T> {
|
|
pub timestamp: u64,
|
|
pub value: T,
|
|
}
|
|
|
|
impl<T> CacheEntry<T> {
|
|
pub fn new(value: T) -> Self {
|
|
Self {
|
|
timestamp: SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_secs(),
|
|
value,
|
|
}
|
|
}
|
|
|
|
pub fn is_expired(&self) -> bool {
|
|
let now = SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_secs();
|
|
now > self.timestamp + CACHE_TTL_SECS
|
|
}
|
|
}
|
|
|
|
lazy_static::lazy_static! {
|
|
/// Cache for individual variable values: key = "workspace_id:path"
|
|
pub static ref VARIABLE_CACHE: Cache<String, CacheEntry<String>> = Cache::new(1000);
|
|
|
|
/// Cache for resource values: key = "workspace_id:path"
|
|
pub static ref RESOURCE_CACHE: Cache<String, CacheEntry<Value>> = Cache::new(1000);
|
|
}
|
|
|
|
/// Generate cache key for variables and resources
|
|
pub fn cache_key(workspace_id: &str, path: &str) -> String {
|
|
format!("{}:{}", workspace_id, path)
|
|
}
|
|
|
|
/// Get cached variable if available and not expired
|
|
pub fn get_cached_variable(workspace_id: &str, path: &str) -> Option<String> {
|
|
let key = cache_key(workspace_id, path);
|
|
VARIABLE_CACHE.get(&key).and_then(|entry| {
|
|
if entry.is_expired() {
|
|
VARIABLE_CACHE.remove(&key);
|
|
None
|
|
} else {
|
|
tracing::debug!("Cache hit for variable {}", key);
|
|
Some(entry.value.clone())
|
|
}
|
|
})
|
|
}
|
|
|
|
/// Cache variable data
|
|
pub fn cache_variable(workspace_id: &str, path: &str, email: &str, variable: String) {
|
|
let key = format!("{}:{}", email, cache_key(workspace_id, path));
|
|
let entry = CacheEntry::new(variable);
|
|
VARIABLE_CACHE.insert(key.clone(), entry);
|
|
tracing::debug!("Cached variable {}", key);
|
|
}
|
|
|
|
/// Get cached resource if available and not expired
|
|
pub fn get_cached_resource(workspace_id: &str, path: &str) -> Option<Value> {
|
|
let key = cache_key(workspace_id, path);
|
|
RESOURCE_CACHE.get(&key).and_then(|entry| {
|
|
if entry.is_expired() {
|
|
RESOURCE_CACHE.remove(&key);
|
|
None
|
|
} else {
|
|
tracing::debug!("Cache hit for resource {}", key);
|
|
Some(entry.value.clone())
|
|
}
|
|
})
|
|
}
|
|
|
|
/// Cache resource data
|
|
pub fn cache_resource(workspace_id: &str, path: &str, resource: Value) {
|
|
let key = cache_key(workspace_id, path);
|
|
let entry = CacheEntry::new(resource);
|
|
RESOURCE_CACHE.insert(key.clone(), entry);
|
|
tracing::debug!("Cached resource {}", key);
|
|
}
|
|
|
|
/// Invalidate specific variable from cache
|
|
pub fn invalidate_variable_cache(workspace_id: &str, path: &str) {
|
|
let key = cache_key(workspace_id, path);
|
|
VARIABLE_CACHE.remove(&key);
|
|
tracing::info!("Variable cache invalidated for {}", key);
|
|
}
|
|
|
|
/// Invalidate specific resource from cache
|
|
pub fn invalidate_resource_cache(workspace_id: &str, path: &str) {
|
|
let key = cache_key(workspace_id, path);
|
|
RESOURCE_CACHE.remove(&key);
|
|
tracing::info!("Resource cache invalidated for {}", key);
|
|
}
|
|
|
|
/// Clear all caches (for testing/debugging)
|
|
#[allow(dead_code)]
|
|
pub fn clear_all_caches() {
|
|
VARIABLE_CACHE.clear();
|
|
RESOURCE_CACHE.clear();
|
|
tracing::debug!("All variable/resource caches cleared");
|
|
}
|