mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-18 16:02:10 +00:00
chore: make rquickjs, kube, otel proxy deps optional behind feature flags
- rquickjs: gated behind `quickjs` feature in windmill-jseval, propagated through windmill-worker/windmill-api, added to oss_core - windmill-autoscaling: made optional in windmill-api (was unconditional), enabled via enterprise feature - opentelemetry-proto, prost, hudsucker, rcgen, hyper-http-proxy, hyper-tls, hyper-util: made optional in windmill-worker, enabled via enterprise feature This significantly reduces compilation time for vanilla `cargo check` without features. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+3
-1
@@ -91,6 +91,7 @@ embedding = ["windmill-api/embedding"]
|
||||
parquet = ["windmill-api/parquet", "windmill-common/parquet", "windmill-worker/parquet", "dep:object_store"]
|
||||
prometheus = ["windmill-common/prometheus", "windmill-api/prometheus", "windmill-worker/prometheus", "windmill-queue/prometheus", "dep:prometheus"]
|
||||
flow_testing = ["windmill-worker/flow_testing"]
|
||||
quickjs = ["windmill-worker/quickjs", "windmill-api/quickjs"]
|
||||
openidconnect = ["windmill-api/openidconnect", "windmill-common/openidconnect"]
|
||||
cloud = ["windmill-queue/cloud", "windmill-worker/cloud", "windmill-common/cloud", "windmill-api/cloud"]
|
||||
jemalloc = ["windmill-common/jemalloc", "dep:tikv-jemallocator", "dep:tikv-jemalloc-sys", "dep:tikv-jemalloc-ctl"]
|
||||
@@ -145,7 +146,8 @@ oss_core = [
|
||||
"embedding", "parquet", "openidconnect", "license",
|
||||
"http_trigger", "zip", "oauth2", "postgres_trigger",
|
||||
"mqtt_trigger", "websocket", "smtp", "native_trigger",
|
||||
"static_frontend", "mcp", "bedrock", "inline_preview"
|
||||
"static_frontend", "mcp", "bedrock", "inline_preview",
|
||||
"quickjs"
|
||||
]
|
||||
ce_core = ["oss_core", "private"]
|
||||
ee_core = [
|
||||
|
||||
@@ -11,7 +11,7 @@ path = "src/lib.rs"
|
||||
[features]
|
||||
default = []
|
||||
private = ["windmill-audit/private", "windmill-common/private", "windmill-api-auth/private", "windmill-store/private", "windmill-api-users/private", "windmill-api-workspaces/private", "windmill-api-groups/private", "windmill-trigger-kafka?/private", "windmill-trigger-postgres?/private", "windmill-trigger-mqtt?/private", "windmill-trigger-websocket?/private", "windmill-trigger-nats?/private", "windmill-trigger-sqs?/private", "windmill-trigger-gcp?/private", "windmill-trigger-email?/private"]
|
||||
enterprise = ["windmill-queue/enterprise", "windmill-audit/enterprise", "windmill-git-sync/enterprise", "windmill-common/enterprise", "windmill-worker?/enterprise", "windmill-api-auth/enterprise", "windmill-store/enterprise", "windmill-api-jobs/enterprise", "windmill-api-scripts/enterprise", "windmill-api-users/enterprise", "windmill-api-workspaces/enterprise", "windmill-api-groups/enterprise", "windmill-trigger/enterprise", "windmill-trigger-kafka?/enterprise", "windmill-trigger-postgres?/enterprise", "windmill-trigger-mqtt?/enterprise", "windmill-trigger-websocket?/enterprise", "windmill-trigger-email?/enterprise", "windmill-trigger-nats?/enterprise", "windmill-trigger-sqs?/enterprise", "windmill-trigger-gcp?/enterprise", "windmill-trigger-http?/enterprise", "windmill-native-triggers?/enterprise"]
|
||||
enterprise = ["windmill-queue/enterprise", "windmill-audit/enterprise", "windmill-git-sync/enterprise", "windmill-common/enterprise", "windmill-worker?/enterprise", "windmill-api-auth/enterprise", "windmill-store/enterprise", "windmill-api-jobs/enterprise", "windmill-api-scripts/enterprise", "windmill-api-users/enterprise", "windmill-api-workspaces/enterprise", "windmill-api-groups/enterprise", "windmill-trigger/enterprise", "windmill-trigger-kafka?/enterprise", "windmill-trigger-postgres?/enterprise", "windmill-trigger-mqtt?/enterprise", "windmill-trigger-websocket?/enterprise", "windmill-trigger-email?/enterprise", "windmill-trigger-nats?/enterprise", "windmill-trigger-sqs?/enterprise", "windmill-trigger-gcp?/enterprise", "windmill-trigger-http?/enterprise", "windmill-native-triggers?/enterprise", "dep:windmill-autoscaling", "windmill-autoscaling/enterprise"]
|
||||
stripe = []
|
||||
inline_preview = ["dep:windmill-worker"]
|
||||
agent_worker_server = ["dep:windmill-worker"]
|
||||
@@ -42,6 +42,7 @@ mcp = ["dep:windmill-mcp", "windmill-mcp/server", "windmill-mcp/auth", "windmill
|
||||
bedrock = ["dep:aws-sdk-bedrock", "dep:aws-sdk-bedrockruntime", "windmill-common/bedrock", "dep:aws-config", "dep:aws-credential-types", "dep:aws-smithy-types"]
|
||||
python = ["windmill-dep-map/python", "dep:windmill-parser-py", "dep:windmill-parser-py-imports", "windmill-api-scripts/python", "windmill-trigger/python", "windmill-common/python"]
|
||||
no_auth = ["windmill-api-auth/no_auth", "windmill-store/no_auth", "windmill-api-users/no_auth"]
|
||||
quickjs = ["windmill-jseval/quickjs"]
|
||||
|
||||
[dependencies]
|
||||
windmill-mcp = { workspace = true, optional = true }
|
||||
@@ -64,7 +65,7 @@ windmill-parser-py = { workspace = true, optional = true }
|
||||
windmill-parser-py-imports = { workspace = true, optional = true }
|
||||
windmill-git-sync.workspace = true
|
||||
windmill-indexer = { workspace = true, optional = true }
|
||||
windmill-autoscaling.workspace = true
|
||||
windmill-autoscaling = { workspace = true, optional = true }
|
||||
windmill-worker = { workspace = true, optional = true }
|
||||
windmill-dep-map.workspace = true
|
||||
tokio.workspace = true
|
||||
|
||||
@@ -10,10 +10,11 @@ path = "src/lib.rs"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
quickjs = ["dep:rquickjs"]
|
||||
|
||||
[dependencies]
|
||||
windmill-common = { workspace = true, default-features = false }
|
||||
rquickjs.workspace = true
|
||||
rquickjs = { workspace = true, optional = true }
|
||||
serde_json.workspace = true
|
||||
tokio.workspace = true
|
||||
tracing.workspace = true
|
||||
|
||||
@@ -21,6 +21,7 @@ use std::sync::Arc;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
#[cfg(feature = "quickjs")]
|
||||
use rquickjs::{
|
||||
async_with,
|
||||
prelude::{Async, Func, MutFn},
|
||||
@@ -63,8 +64,9 @@ lazy_static! {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// ── Shared helper functions ───────────────────────────────────────────
|
||||
// ── Shared helper functions (quickjs-only) ──────────────────────────
|
||||
|
||||
#[cfg(feature = "quickjs")]
|
||||
pub fn replace_with_await(expr: String, fn_name: &str) -> String {
|
||||
let sep = format!("{}(", fn_name);
|
||||
let mut split = expr.split(&sep);
|
||||
@@ -75,10 +77,12 @@ pub fn replace_with_await(expr: String, fn_name: &str) -> String {
|
||||
s
|
||||
}
|
||||
|
||||
#[cfg(feature = "quickjs")]
|
||||
pub fn replace_with_await_result(expr: String) -> String {
|
||||
RE.replace_all(&expr, "(await $r)").to_string()
|
||||
}
|
||||
|
||||
#[cfg(feature = "quickjs")]
|
||||
fn add_closing_bracket(s: &str) -> String {
|
||||
let mut s = s.to_string();
|
||||
let mut level = 1;
|
||||
@@ -194,23 +198,20 @@ pub async fn handle_full_regex(
|
||||
return None;
|
||||
}
|
||||
|
||||
#[cfg(feature = "quickjs")]
|
||||
use windmill_common::utils::unsafe_raw;
|
||||
|
||||
// ── QuickJS evaluation ───────────────────────────────────────────────
|
||||
|
||||
#[cfg(feature = "quickjs")]
|
||||
|
||||
/// Shared state for async operations within QuickJS
|
||||
#[derive(Clone)]
|
||||
struct AsyncOpState {
|
||||
client: AuthedClient,
|
||||
}
|
||||
|
||||
/// Evaluates a JavaScript expression using QuickJS runtime.
|
||||
///
|
||||
/// This function provides flow expression evaluation using QuickJS
|
||||
/// instead of deno_core/V8 for significantly faster startup times.
|
||||
///
|
||||
/// Unlike deno_core, this uses true async Rust callbacks for `variable()`,
|
||||
/// `resource()`, and `results.xxx` access - no pre-fetching required.
|
||||
#[cfg(feature = "quickjs")]
|
||||
pub async fn eval_timeout_quickjs(
|
||||
expr: String,
|
||||
transform_context: HashMap<String, Arc<Box<RawValue>>>,
|
||||
@@ -301,9 +302,10 @@ pub async fn eval_timeout_quickjs(
|
||||
})??
|
||||
}
|
||||
|
||||
/// Memory limit for QuickJS runtime (32MB).
|
||||
#[cfg(feature = "quickjs")]
|
||||
const QUICKJS_MEMORY_LIMIT: usize = 32 * 1024 * 1024;
|
||||
|
||||
#[cfg(feature = "quickjs")]
|
||||
async fn eval_quickjs_inner(
|
||||
expr: &str,
|
||||
transform_context: HashMap<String, Arc<Box<RawValue>>>,
|
||||
@@ -441,7 +443,7 @@ async fn eval_quickjs_inner(
|
||||
.await
|
||||
}
|
||||
|
||||
/// Set up async variable() and resource() functions using true Rust async callbacks.
|
||||
#[cfg(feature = "quickjs")]
|
||||
fn setup_async_ops<'js>(
|
||||
ctx: &rquickjs::Ctx<'js>,
|
||||
globals: &Object<'js>,
|
||||
@@ -509,7 +511,7 @@ fn setup_async_ops<'js>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set up stub functions that throw errors when no client is available
|
||||
#[cfg(feature = "quickjs")]
|
||||
fn setup_stub_functions<'js>(
|
||||
ctx: &rquickjs::Ctx<'js>,
|
||||
_globals: &Object<'js>,
|
||||
@@ -531,7 +533,7 @@ fn setup_stub_functions<'js>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set up the `results` Proxy object with dynamic access to step results.
|
||||
#[cfg(feature = "quickjs")]
|
||||
fn setup_results_proxy<'js>(
|
||||
ctx: &rquickjs::Ctx<'js>,
|
||||
globals: &Object<'js>,
|
||||
@@ -657,7 +659,7 @@ fn setup_results_proxy<'js>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Convert a serde_json::Value to a QuickJS Value
|
||||
#[cfg(feature = "quickjs")]
|
||||
fn json_to_js<'js>(
|
||||
ctx: &rquickjs::Ctx<'js>,
|
||||
val: &serde_json::Value,
|
||||
@@ -696,6 +698,7 @@ fn json_to_js<'js>(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "quickjs")]
|
||||
fn should_add_return_quickjs(expr: &str) -> bool {
|
||||
let trimmed = expr.trim();
|
||||
|
||||
@@ -741,6 +744,7 @@ fn should_add_return_quickjs(expr: &str) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(feature = "quickjs")]
|
||||
fn contains_semicolon_outside_strings(expr: &str) -> bool {
|
||||
let mut in_single_quote = false;
|
||||
let mut in_double_quote = false;
|
||||
@@ -769,14 +773,14 @@ fn contains_semicolon_outside_strings(expr: &str) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(feature = "quickjs")]
|
||||
fn quickjs_error_to_anyhow(err: rquickjs::CaughtError<'_>) -> anyhow::Error {
|
||||
anyhow::anyhow!("QuickJS evaluation error: {}", err)
|
||||
}
|
||||
|
||||
// ── eval_simple_js for windmill-api batch rerun ──────────────────────
|
||||
|
||||
/// Evaluate a JS expression with named JSON globals in scope.
|
||||
/// Used by windmill-api for batch rerun arg transforms.
|
||||
#[cfg(feature = "quickjs")]
|
||||
pub async fn eval_simple_js(
|
||||
expr: String,
|
||||
globals: HashMap<String, serde_json::Value>,
|
||||
@@ -819,9 +823,32 @@ pub async fn eval_simple_js(
|
||||
})??
|
||||
}
|
||||
|
||||
// ── Fallback stubs when quickjs is disabled ──────────────────────────
|
||||
|
||||
#[cfg(not(feature = "quickjs"))]
|
||||
pub async fn eval_timeout_quickjs(
|
||||
_expr: String,
|
||||
_transform_context: HashMap<String, Arc<Box<RawValue>>>,
|
||||
_flow_input: Option<mappable_rc::Marc<HashMap<String, Box<RawValue>>>>,
|
||||
_flow_env: Option<&HashMap<String, Box<RawValue>>>,
|
||||
_authed_client: Option<&windmill_common::client::AuthedClient>,
|
||||
_by_id: Option<&IdContext>,
|
||||
_ctx: Option<Vec<(String, String)>>,
|
||||
) -> anyhow::Result<Box<RawValue>> {
|
||||
anyhow::bail!("quickjs feature is not enabled")
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "quickjs"))]
|
||||
pub async fn eval_simple_js(
|
||||
_expr: String,
|
||||
_globals: HashMap<String, serde_json::Value>,
|
||||
) -> anyhow::Result<Box<RawValue>> {
|
||||
anyhow::bail!("quickjs feature is not enabled")
|
||||
}
|
||||
|
||||
// ── Tests ────────────────────────────────────────────────────────────
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(all(test, feature = "quickjs"))]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
@@ -13,7 +13,7 @@ default = []
|
||||
private = []
|
||||
mcp = ["dep:windmill-mcp"]
|
||||
prometheus = ["dep:prometheus", "windmill-common/prometheus"]
|
||||
enterprise = ["windmill-queue/enterprise", "windmill-git-sync/enterprise", "windmill-common/enterprise", "dep:pem", "dep:tokio-util"]
|
||||
enterprise = ["windmill-queue/enterprise", "windmill-git-sync/enterprise", "windmill-common/enterprise", "dep:pem", "dep:tokio-util", "dep:opentelemetry-proto", "dep:prost", "dep:hudsucker", "dep:rcgen", "dep:hyper-http-proxy", "dep:hyper-tls", "dep:hyper-util"]
|
||||
mssql = ["dep:tiberius"]
|
||||
mssql-kerberos = ["mssql", "tiberius/integrated-auth-gssapi"] # Linux/Unix integrated auth
|
||||
mssql-winauth = ["mssql", "tiberius/winauth"] # Windows integrated auth
|
||||
@@ -37,6 +37,7 @@ nu = ["dep:windmill-parser-nu"]
|
||||
java = ["dep:windmill-parser-java"]
|
||||
ruby = ["dep:windmill-parser-ruby"]
|
||||
duckdb = ["dep:libloading"]
|
||||
quickjs = ["windmill-jseval/quickjs"]
|
||||
bedrock = ["dep:aws-sdk-bedrockruntime", "windmill-common/bedrock", "dep:aws-config", "dep:aws-credential-types", "dep:aws-smithy-types"]
|
||||
|
||||
[dependencies]
|
||||
@@ -127,18 +128,18 @@ process-wrap.workspace = true
|
||||
async-once-cell.workspace = true
|
||||
libloading = { workspace = true, optional = true }
|
||||
|
||||
opentelemetry-proto.workspace = true
|
||||
opentelemetry-proto = { workspace = true, optional = true }
|
||||
opentelemetry = { workspace = true, optional = true }
|
||||
tracing-opentelemetry = { workspace = true, optional = true }
|
||||
prost.workspace = true
|
||||
prost = { workspace = true, optional = true }
|
||||
axum.workspace = true
|
||||
bollard = { workspace = true, optional = true }
|
||||
oracle = { workspace = true, optional = true }
|
||||
hudsucker.workspace = true
|
||||
hyper-http-proxy.workspace = true
|
||||
hyper-tls.workspace = true
|
||||
hyper-util.workspace = true
|
||||
rcgen.workspace = true
|
||||
hudsucker = { workspace = true, optional = true }
|
||||
hyper-http-proxy = { workspace = true, optional = true }
|
||||
hyper-tls = { workspace = true, optional = true }
|
||||
hyper-util = { workspace = true, optional = true }
|
||||
rcgen = { workspace = true, optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
libffi-sys = { workspace = true, optional = true }
|
||||
|
||||
Reference in New Issue
Block a user