2.3 KiB
One Engine Instance Per Call
{{#include ../links.md}}
Usage Scenario
-
A system where scripts are called a lot, in tight loops or in parallel.
-
Keeping a global [
Engine
] instance is sub-optimal due to contention and locking. -
Scripts need to be executed independently from each other, perhaps concurrently.
-
Scripts are used to [create Rust closure][
Func
] that are stored and may be called at any time, perhaps concurrently. In this case, the [Engine
] instance is usually moved into the closure itself.
Key Concepts
-
Create a single instance of each standard [package] required. To duplicate
Engine::new
, create aStandardPackage
. -
Gather up all common custom functions into a [custom package].
-
Store a global
AST
for use with all engines. -
Always use
Engine::new_raw
to create a [rawEngine
], instead ofEngine::new
which is much more expensive. A [rawEngine
] is extremely cheap to create.Registering the
StandardPackage
into a [rawEngine
] viaEngine::register_global_module
is essentially the same asEngine::new
.However, because packages are shared, using existing package is much cheaper than registering all the functions one by one.
-
Register the required packages with the [raw
Engine
] viaEngine::register_global_module
, usingPackage::as_shared_module
to obtain a shared [module].
Examples
use rhai::packages::{Package, StandardPackage};
let ast = /* ... some AST ... */;
let std_pkg = StandardPackage::new();
let custom_pkg = MyCustomPackage::new();
let make_call = |x: i64| -> Result<(), Box<EvalAltResult>> {
// Create a raw Engine - extremely cheap
let mut engine = Engine::new_raw();
// Register packages as global modules - cheap
engine.register_global_module(std_pkg.as_shared_module());
engine.register_global_module(custom_pkg.as_shared_module());
// Create custom scope - cheap
let mut scope = Scope::new();
// Push variable into scope - relatively cheap
scope.push("x", x);
// Evaluate script.
engine.consume_ast_with_scope(&mut scope, &ast)
};
// The following loop creates 10,000 Engine instances!
for x in 0..10_000 {
make_call(x)?;
}