Orama JS Pool provides a pool of JavaScript engines (using the Deno runtime via deno_core) for running JavaScript code from Rust. It is designed for high-throughput, parallel, and optionally sandboxed execution of JS functions, supporting both sync and async workflows.
Here's how to run an async JavaScript function using a pool of JS engines:
use orama_js_pool::{ExecOptions, Pool, RuntimeError};
use std::time::Duration;
static CODE_ASYNC_SUM: &str = r#"
async function async_sum(a, b) {
await new Promise(resolve => setTimeout(resolve, 100));
return a + b
}
export default { async_sum };
"#;
#[tokio::main]
async fn main() -> Result<(), RuntimeError> {
// Create a pool with 10 JS workers, with the module loaded
let pool = Pool::builder()
.max_size(10) // number of workers in the pool
.with_evaluation_timeout(Duration::from_millis(200)) // module load timeout
.with_execution_timeout(Duration::from_secs(30)) // default execution timeout
.add_module("async_calculator", CODE_ASYNC_SUM.to_string())
.build()
.await?;
let params = vec![1, 2];
let result: u8 = pool
.exec(
"async_calculator", // module name
"async_sum", // function name
¶ms, // input parameters
ExecOptions::new().with_timeout(Duration::from_millis(200)), // override pool timeout
)
.await?;
println!("async_sum(1, 2) == {result}");
assert_eq!(result, 3);
Ok(())
}Main entry point. Manages a pool of JS workers, each with loaded modules.
Pool::builder()— creates a new pool builderPoolBuilder::max_size(n)— sets worker pool sizePoolBuilder::with_evaluation_timeout(duration)— module load timeout (default: 5 seconds)PoolBuilder::with_execution_timeout(duration)— default execution timeout for all workers (default: 30 seconds)PoolBuilder::with_max_executions(limit)— recycle workers after n executions (prevents memory leaks)PoolBuilder::with_domain_permission(permission)— restrict network access at pool levelPoolBuilder::add_module(name, code)— loads a module into all workersexec(module_name, function_name, params, ExecOptions)— executes a function
Per-execution configuration (all optional, overrides pool defaults):
with_timeout(duration): Override pool execution timeout for this specific callwith_domain_permission(permission): Override pool domain permission for this specific callwith_stdout_sender(sender): Capture console.log/error output
All errors (startup, execution, JS exceptions) are reported as RuntimeError.
- Parallel execution: Multiple requests handled concurrently
- Async and sync JS support: Run both types of JS functions
- Sandboxing: Restrict network access via domain permissions (allow/deny lists)
- Flexible timeouts: Set default timeouts at pool level, override per execution
evaluation_timeout: Controls how long module loading can take (default: 5s)execution_timeout: Controls how long function execution can take (default: 30s)
- Typed input/output: Use Rust types for parameters and results (via serde)
- Worker recycling: Prevent memory leaks with configurable max executions per worker
If your JS function is an async generator, you can use streaming APIs (see crate docs for details).
Licensed under the Affero GPL v3 license. See the LICENSE file for details.