arc feature to enable using Engine and other data structures from multiple threads (#142)

* `arc` feature to make engine usable from multiple threads.

`arc` is turned on by default. When enabled, std::sync::Arc
will be used instead of std::rc::Rc. The former makes regorus
types like Engine, Value, ast nodes etc Send, allowing for
usability from multiple threads.
Arc would add a performance overhead though since the reference
counting will now become atomic.

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>

* Make engine and related types Debug

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>

* Input, Data as json. Evaluate bool queries.

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>

---------

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2024-02-13 10:23:19 -08:00
committed by GitHub
parent 13eb06e4be
commit 53b990f97d
14 changed files with 96 additions and 24 deletions

View File

@@ -17,7 +17,7 @@ use anyhow::{bail, Result};
/// The Rego evaluation engine.
///
#[derive(Clone)]
#[derive(Debug, Clone)]
pub struct Engine {
modules: Vec<Ref<Module>>,
interpreter: Interpreter,
@@ -120,6 +120,11 @@ impl Engine {
self.interpreter.set_input(input);
}
pub fn set_input_json(&mut self, input_json: &str) -> Result<()> {
self.set_input(Value::from_json_str(input_json)?);
Ok(())
}
/// Clear the data document.
///
/// The data document will be reset to an empty object.
@@ -182,6 +187,10 @@ impl Engine {
self.interpreter.get_data_mut().merge(data)
}
pub fn add_data_json(&mut self, data_json: &str) -> Result<()> {
self.add_data(Value::from_json_str(data_json)?)
}
/// Set whether builtins should raise errors strictly or not.
///
/// Regorus differs from OPA in that by default builtins will
@@ -256,6 +265,14 @@ impl Engine {
)
}
pub fn eval_bool_query(&mut self, query: String, enable_tracing: bool) -> Result<bool> {
let results = self.eval_query(query, enable_tracing)?;
if results.result.len() != 1 || results.result[0].expressions.len() != 1 {
bail!("query did not produce exactly one value");
}
results.result[0].expressions[0].value.as_bool().copied()
}
#[doc(hidden)]
fn prepare_for_eval(&mut self, enable_tracing: bool) -> Result<()> {
self.interpreter.set_traces(enable_tracing);