Skip to main content

Ctx

Struct Ctx 

Source
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>

Source

pub fn info(&self) -> &CallInfo<'r>

The static facts about this call.

Source

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.

Source

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.

Source

pub fn payload(&self) -> &OwnedDataValue

The message’s payload, which no expression reads.

Source

pub fn exprs(&self) -> &ExprEngine

The engine the program was compiled with, for an evaluation over a root of the function’s own.

Source

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.

Source

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.

Source

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.

Source

pub fn accountant(&self) -> Option<&'r dyn RunAccountant>

The host-owned RunAccountant attached to this run, if any, so a function can charge domain-specific work units via RunAccountant::charge_custom.

Source

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.

Source

pub fn render<'s>(&'s self, doc: &'s Interpolated) -> Rendered<'s>

doc with each hole looked up once, as Self::get would, and lent where it was found; a hole that finds nothing yields its default. No tree is built: the Rendered serializes the document’s skeleton with each value in place, so a consumer that is itself a serializer pays for no intermediate value.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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 Debug for Ctx<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

The call’s facts and whether it has written; never the context.

Source§

impl Resolver for &Ctx<'_>

Source§

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 more
Source§

fn render(&mut self, doc: &Interpolated) -> Result<OwnedDataValue>

doc rendered, as an owned tree: each hole’s value, or its default. Read more

Auto Trait Implementations§

§

impl<'r> !RefUnwindSafe for Ctx<'r>

§

impl<'r> !UnwindSafe for Ctx<'r>

§

impl<'r> Freeze for Ctx<'r>

§

impl<'r> Send for Ctx<'r>

§

impl<'r> Sync for Ctx<'r>

§

impl<'r> Unpin for Ctx<'r>

§

impl<'r> UnsafeUnpin for Ctx<'r>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.