pub struct Ctx<'r> { /* private fields */ }Expand description
A Function’s view of one call.
It reads the run’s single view of the context, so no view is built per
call, and keeps the call’s writes in an overlay of its own: a read
sees them over the run’s context, and they reach the message only when
the call returns Ok (whatever the Outcome). An Err
drops them, and their Changes, and keeps the records the call added.
Once the call has written, each evaluation splices the overlay onto the
view in an arena borrowed from a pool for that evaluation only. Ctx
holds no arena, so it is Send and Sync. A host never builds one: the
engine hands it to Function::call and to each
CallLayer, and testing::call
to one call outside a run:
use dataflow_rs::datavalue::OwnedDataValue;
use dataflow_rs::function::testing::{self, Write};
use dataflow_rs::run::Change;
use dataflow_rs::{Ctx, Function, Message, Outcome, Path, Result};
use serde_json::json;
/// Counts visits at `data.visits`, and drops the stale `data.cache`.
struct Visit;
impl Function for Visit {
type Config = ();
async fn call(&self, ctx: &mut Ctx<'_>, _cfg: &()) -> Result<Outcome> {
let visits: Path = "data.visits".parse()?;
let seen = ctx.get(&visits).and_then(|v| v.as_i64()).unwrap_or(0);
ctx.set(&visits, OwnedDataValue::from(&json!(seen + 1)))?;
// The call reads its own write at once; the message, once the
// call returns `Ok`.
assert_eq!(ctx.get(&visits).and_then(|v| v.as_i64()), Some(seen + 1));
ctx.remove(&"data.cache".parse()?)?;
Ok(Outcome::Ok)
}
}
let dv = |v: serde_json::Value| OwnedDataValue::from(&v);
let data = dv(json!({"visits": 1, "cache": "stale"}));
let called = testing::call(Visit, json!({}))
.message(Message::from_parts(OwnedDataValue::Null, data, OwnedDataValue::Null))
.await;
let visits: Path = "data.visits".parse().unwrap();
assert_eq!(called.writes[0], (visits, Write::Set(dv(json!(2)))));
assert_eq!(called.writes[1].1, Write::Removed);
assert_eq!(
called.changes[0],
Change::write("data.visits", dv(json!(1)), dv(json!(2)))
);
assert_eq!(called.message.context().data(), &dv(json!({"visits": 2})));Implementations§
Source§impl<'r> Ctx<'r>
impl<'r> Ctx<'r>
Sourcepub fn input(&self) -> Result<OwnedDataValue>
pub fn input(&self) -> Result<OwnedDataValue>
The callee’s config resolved for this call: every field with a value,
set by the input or by its default, keyed by its authored key, in
declaration order, an Option left unset absent, as
FunctionConfig::resolve gives it
over the context as this call sees it, a fan-out element’s binding
included. A hand-written config gives what its own resolve does.
A field of type f64 writes a float, 2.0 for an authored 2 too,
where a Templated number field writes the
number as it was authored.
A field whose expression reads a secret is null, the one redaction
the engine writes, as TraceOptions::redact
writes a redacted path’s value, and it is never evaluated, so not
even its error can carry the value: a logging layer or a dry run
reads the input without reading a secret. The function itself
reads its own fields, secrets included, through Self::eval.
§Errors
The first field’s that fails: ErrorKind::Budget when the
operation ceiling is exceeded, ErrorKind::Eval for any other
evaluation failure, ErrorKind::Config for a serde field that does
not serialize.
Sourcepub fn resolve<C: FunctionConfig>(&self, cfg: &C) -> Result<OwnedDataValue>
pub fn resolve<C: FunctionConfig>(&self, cfg: &C) -> Result<OwnedDataValue>
cfg resolved for this call, unredacted:
FunctionConfig::resolve over the
context as this call sees it, a fan-out element’s binding included,
with every expression evaluated, a secret-reading one too. It is
Self::input’s counterpart: input is what a layer or a dry run
reads, and this is the function’s own view of its config, which it
may hand on whole.
§Errors
The first field’s that fails: ErrorKind::Budget when the
operation ceiling is exceeded, ErrorKind::Eval for any other
evaluation failure, ErrorKind::Config for a serde field that does
not serialize.
Sourcepub fn payload(&self) -> &OwnedDataValue
pub fn payload(&self) -> &OwnedDataValue
The message’s payload, which no expression reads.
Sourcepub fn exprs(&self) -> &ExprEngine
pub fn exprs(&self) -> &ExprEngine
The engine the program was compiled with, for an evaluation over a root of the function’s own.
Sourcepub fn secret(&self, name: &str) -> Option<&OwnedDataValue>
pub fn secret(&self, name: &str) -> Option<&OwnedDataValue>
The secret at the dotted path name, from the engine’s store. What a
function does with it is the function’s: the engine never records it.
Sourcepub fn deadline(&self) -> Option<Instant>
pub fn deadline(&self) -> Option<Instant>
When the run must end, if it has a deadline: a run this function
starts passes it on, or an earlier one. An Err this call returns
once the deadline has passed, such as that run’s own TimedOut, ends
this run TimedOut too.
Sourcepub fn cancel(&self) -> Option<&CancelToken>
pub fn cancel(&self) -> Option<&CancelToken>
The run’s cancellation token, if it has one: a child of it cancels a
run this function starts along with this one, so that run ends
Cancelled and reports it rather than being dropped. An Err this
call returns once the token is cancelled ends this run Cancelled.
Sourcepub fn get(&self, path: &Path) -> Option<Cow<'_, OwnedDataValue>>
pub fn get(&self, path: &Path) -> Option<Cow<'_, OwnedDataValue>>
The value at path as this call sees it: its own writes, over a
fan-out element’s bindings, over the run’s context. Borrowed unless
it must be put together, when it is converted: a value only the run’s
view knows, or one with this call’s writes or a binding below path,
such as temp_data while temp_data.p is bound.
Sourcepub fn render<'s>(&'s self, doc: &'s Interpolated) -> Rendered<'s>
pub fn render<'s>(&'s self, doc: &'s Interpolated) -> Rendered<'s>
Sourcepub fn eval<'e, T: FromValue>(&self, expr: &'e Expr<T>) -> Result<T::Out<'e>>
pub fn eval<'e, T: FromValue>(&self, expr: &'e Expr<T>) -> Result<T::Out<'e>>
Evaluates expr against the context as this call sees it. A folded
constant is lent from expr and takes no arena; anything else is
evaluated in a pooled arena and converted to T before the arena goes
back.
§Errors
ErrorKind::Budget when the
operation ceiling is exceeded; ErrorKind::Eval
for any other failure, including a result that is not a T.
Sourcepub fn set(&mut self, path: &Path, value: OwnedDataValue) -> Result<()>
pub fn set(&mut self, path: &Path, value: OwnedDataValue) -> Result<()>
Assigns value at path, by Path::set’s rules: a hop that cannot
continue writes nothing. The Change is recorded first, under
capture, with the value this call sees there now, so a second write to
one path leaves two Changes and one value. At a root the write
replaces the root, and its Change says so
(replaced).
§Errors
ErrorKind::Config when path is a
root and value is not an object.
Sourcepub fn emit(&mut self, out: &Output, value: OwnedDataValue) -> Result<()>
pub fn emit(&mut self, out: &Output, value: OwnedDataValue) -> Result<()>
Writes value through out, as Self::set does: at its path
when it is literal, else at the path it evaluates to now, against the
context as this call sees it.
§Errors
Self::eval’s, when out is computed and does not give a path;
Self::set’s.
Sourcepub fn primary_output(&self) -> Option<&'r Output>
pub fn primary_output(&self) -> Option<&'r Output>
The callee’s primary output, the one Self::emit_default writes
through, as the call site set it: None when the config declares
none, or leaves an optional one unset. A layer reads it to know
whether, and where, an answer would be written. It borrows the
callee, not this context, so a layer can Self::emit through it.
Sourcepub fn emit_default(&mut self, value: OwnedDataValue) -> Result<()>
pub fn emit_default(&mut self, value: OwnedDataValue) -> Result<()>
Self::emit through the function’s primary output, the one its
config’s FunctionConfig::primary_output
names.
§Errors
ErrorKind::Config when the config has no primary output, or
leaves an optional one unset, which the error names; Self::emit’s.
Sourcepub fn remove(&mut self, path: &Path) -> Result<()>
pub fn remove(&mut self, path: &Path) -> Result<()>
Removes the value at path, recording the removal under capture.
Nothing there is nothing to do, and records nothing.
§Errors
ErrorKind::Config when path is a
root.
Sourcepub fn record_error(&mut self, e: ErrorRecord)
pub fn record_error(&mut self, e: ErrorRecord)
Adds a record to the message’s errors, whatever the call returns. What the record leaves unset the engine fills: the workflow’s and the task’s ids, the run’s timestamp, and in a fan-out the element’s index.
Trait Implementations§
Source§impl Resolver for &Ctx<'_>
impl Resolver for &Ctx<'_>
Source§fn eval(&mut self, expr: &dyn ResolveExpr) -> Result<OwnedDataValue>
fn eval(&mut self, expr: &dyn ResolveExpr) -> Result<OwnedDataValue>
expr evaluated, as an owned value: a number for a u64, i64 or
f64 expression, a boolean for a bool one, a string for a String
one, a path’s dotted text for a Path one, and the value itself for
any other. A folded constant is its value, evaluated never. Read moreSource§fn render(&mut self, doc: &Interpolated) -> Result<OwnedDataValue>
fn render(&mut self, doc: &Interpolated) -> Result<OwnedDataValue>
doc rendered, as an owned tree: each hole’s value, or its default. Read more