Circuit
The Circuit describes a control system as an execution graph. The Circuit is defined as a graph of interconnected signal processing components. Signals flow between components through ports. As signals traverse the circuit, they get processed, stored within components or get acted upon (for example: load-throttling, rate-limit, auto-scale and so on). The Circuit is evaluated periodically to respond to changes in signal readings.
Component
The building blocks of a circuit are components. Each component has input ports
(in_ports
) and output ports (out_ports
). The exact ports available are
determined by the type of component. Each port can be associated
with a signal. Components get chained to one another based on the name
of the signal.
Signal
The Signal represents a float64
value that updates with every tick
of circuit execution. Every signal must have a name to uniquely identify it
within a circuit.
The output port on a component can emit a signal. No other port (on any component) in the circuit can emit a signal with the same name.
To receive a named signal at a component, it must be defined exactly once as an output at some component in the circuit. Once defined, a signal can be received at other components that have an input port with the same name.
Circuit Runtime
The Circuit evaluates at a constant tick frequency. Each round of evaluation
is called a tick. The evaluation_interval
parameter in the policy
spec configures how often the circuit evaluates (ticks).
On every tick, each component in the circuit gets executed exactly once. Components get executed as they become ready. A component is ready if all its input signals are available.
During execution, the input signals are processed, and output signals are emitted by the component. Any looping signals are saved and consumed by the circuit in the next tick.
Circuit runtime provides highly predictable execution semantics. Any timed operations such as PromQL queries are synchronized to run on multiples of ticks. For PromQL queries, this ensures that all the queries that fire in the same tick return results together in a future tick.
Looping Signals
Circuit execution graph can have loops. Looping signals enable expression of powerful paradigms such as integration using basic arithmetic components.
Despite loops, the execution is still performed on a directed acyclic graph. Before execution, loops are detected in the circuit. Each loop is unlinked at the component with the smallest index (in list of components). The unlinked component ports consume looping signals. A looping signal has the value of the unlinked signal from the previous tick.
Example Components
The exhaustive list of the built-in components can be found in the policy reference.
Examples of built-in components include:
- Query: These components emit signals into the circuit from outside.
- PromQL: Converts results from a PromQL query into a signal.
- Signal Processors: These components transform input signal(s) into output
signal(s).
- Arithmetic: These components perform basic arithmetic operations on
signal(s).
- Arithmetic Combinator: This component takes two input signals and performs a basic arithmetic operation to generate an output signal.
- Max and Min: These components take multiple input or output signals and emit the maximum or minimum of those signals.
- Transformers: These components transform an input signal into an output
signal based on past state.
- EMA: Exponential moving average.
- Decider and Switcher: These components work in tandem to make the circuit adapt based on conditions.
- Arithmetic: These components perform basic arithmetic operations on
signal(s).
- Controllers: Controllers are an essential part of a closed loop control
system. A controller takes as input a signal, a setpoint and emits the
suggested value of the control variable as output. The aim of the controller
is to make the signal achieve the setpoint.
- Gradient Controller: This controller acts on the ratio of setpoint and signal.
- Actuators: Actuators are components which act on signals and interface
with external systems to perform actions such as throttling and queuing
traffic, changing rate limits or auto-scaling.
- Load Scheduler: Takes load multiplier as a signal which determines the proportion of tokens to accept relative to past window.
- Rate Limiter: Take fill rate and bucket capacity as signals which determines the API rate limit for each user or label value.