-
Notifications
You must be signed in to change notification settings - Fork 21
Configuration (v0.4.0)
Zenoh-Flow allows passing values from the different descriptor files to the node. These values are defined in the configuration
part of the descriptor, each value being associated to a key. The main advantage of the configuration is that it allows modifying the behavior of a node without having to modify the code.
When coupled with the Composition (TBD Wiki + Link), it is possible to write different configurations at different levels that target the same keys.
This page aims at explaining (i) how to write a Configuration and (ii) the hierarchy Zenoh-Flow enforces when several configurations target the same keys.
In YAML terms, a configuration
section is an "object" and must follow this format:
configuration:
key-1: value
key-2: value
key-3: value
The values accepted are listed here. In short, a value can be:
- null,
- a boolean,
- a number,
- a sequence (e.g. array),
- a nested object,
- an enum variant (through a tag).
Note that any and all configuration sections are optional.
A configuration section is accepted at the following places:
- (global outer) in a data flow descriptor in a dedicated section,
- (global inner) in a data flow descriptor under each node listing,
- (composite outer) in a composite operator descriptor in a dedicated section,
- (composite inner) in a composite operator descriptor under each operator listing,
- (leaf) in a node declaration in a dedicated section.
Between parenthesis is the name we will be using in the rest of this page. The difference between outer and inner (regardless of the descriptor file) is the scope to which they apply: the outer configuration will apply to all nodes in the descriptor file, the inner configuration will apply only to the node it appears in.
Let us illustrate each section.
flow: test
# "global outer" configuration section
configuration:
foo: 1
bar: "Hello World!"
sources:
- id: source-1
uri: file:///home/zenoh-flow/sources/source-1.so
# "global inner" configuration section
configuration:
foo: 3.14
operators:
- id: operator-1
uri: file:///home/zenoh-flow/operators/operator-1.so
# "global inner" configuration section
configuration:
bar: 3.14
sinks:
- id: sink-1
uri: file:///home/zenoh-flow/sinks/sink-1.so
# the "global inner" configuration is optional.
links:
# omitted for clarity
id: operator-composite
# "composite outer" configuration section
configuration:
foo: 2
bar: "Hello Composite!"
inputs:
- id: operator-composite-in
node: sub-operator-1
input: sub-operator-1-in
outputs:
- id: operator-composite-out
node: sub-operator-2
output: sub-operator-2-out
operators:
- id: sub-operator-1
descriptor: ./src/model/dataflow/tests/sub-operator-1.yml
# "composite inner" configuration section
configuration:
foo: null
- id: sub-operator-2
descriptor: ./src/model/dataflow/tests/sub-operator-2.yml
links:
# omitted for clarity
id: source-1
# "leaf" configuration section
configuration:
foo: "Hello Source!"
uri: file://source-1.so
outputs:
- id: source-1-out
type: _any_
tags: []
As one can see, the same keys are used in the different configuration sections. Then, what is the value that the node will eventually see when the data flow is instantiated?
The hierarchy enforced by Zenoh-Flow is as follows:
global inner > global outer > composite inner > composite outer > leaf
There are two main "aspects" in this hierarchy:
- global > composite > leaf,
- inner > outer.
The rationale behind 1. is that nodes (the leaves) can be developed separately from the data flows they will be running in. What this means is that, potentially, the person creating the data flow will not have access to the descriptor of the node and thus will not be able to modify its configuration. Hence, the leaf must be at the bottom of the hierarchy. Similar reasoning leads to having the composite above the leaf and below the global.
The rationale behind 2. is the ability to apply a configuration to all nodes (through the "outer") and to specialize it to a restricted few (through the "inner").
Let us illustrate this with an example:
flow: test
configuration:
foo: "global-outer"
bar: "global-outer"
operators:
- id: operator-composite
uri: file://./operator-composite.yml
configuration:
bar: "global-inner"
# the rest is omitted for clarity
id: operator-composite
configuration:
foo: "composite-outer"
bar: "composite-outer"
baz: "composite-outer"
operators:
- id: sub-operator
descriptor: ./sub-operator.yml
configuration:
buzz: "composite-inner"
# the rest is omitted for clarity
id: sub-operator
# "leaf" configuration section
configuration:
foo: "leaf"
bar: "leaf"
baz: "leaf"
buzz: "leaf"
quux: "leaf"
# the rest is omitted for clarity
The configuration that the sub-operator
will see is:
foo: "global-outer"
bar: "global-inner"
baz: "composite-outer"
buzz: "composite-inner"
quux: "leaf"
-
Descriptor
- Data flow descriptor
-
Node descriptor
- (optional) Vars
- (optional) Configuration
- Inputs and/or Outputs
- URI
- Composite Operator
-
Node Implementation
-
Advanced