1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
//! This crate enables you to create nodes for the [Dora] dataflow framework.
//!
//! [Dora]: https://dora-rs.ai/
//!
//! ## The Dora Framework
//!
//! Dora is a dataflow frame work that models applications as a directed graph, with nodes
//! representing operations and edges representing data transfer.
//! The layout of the dataflow graph is defined through a YAML file in Dora.
//! For details, see our [Dataflow Specification](https://dora-rs.ai/docs/api/dataflow-config/)
//! chapter.
//!
//! Dora nodes are typically spawned by the Dora framework, instead of spawning them manually.
//! If you want to spawn a node manually, define it as a [_dynamic_ node](#dynamic-nodes).
//!
//! ## Normal Usage
//!
//! In order to connect your executable to Dora, you need to initialize a [`DoraNode`].
//! For standard nodes, the recommended initialization function is [`init_from_env`][`DoraNode::init_from_env`].
//! This function will return two values, a [`DoraNode`] instance and an [`EventStream`]:
//!
//! ```no_run
//! use dora_node_api::DoraNode;
//!
//! let (mut node, mut events) = DoraNode::init_from_env()?;
//! # Ok::<(), eyre::Report>(())
//! ```
//!
//! You can use the `node` instance to send outputs and retrieve information about the node and
//! the dataflow. The `events` stream yields the inputs that the node defines in the dataflow
//! YAML file and other incoming events.
//!
//! ### Sending Outputs
//!
//! The [`DoraNode`] instance enables you to send outputs in different formats.
//! For best performance, use the [Arrow](https://arrow.apache.org/docs/index.html) data format
//! and one of the output functions that utilizes shared memory.
//!
//! ### Receiving Events
//!
//! The [`EventStream`] implements the [`Stream`](futures::Stream) trait, yielding the incoming
//! [`Event`]s. Iterate it asynchronously with [`StreamExt::next`](futures::StreamExt::next), or use
//! the synchronous [`recv`](EventStream::recv) loop.
//!
//! Nodes should iterate over this event stream and react to events that they are interested in.
//! Typically, the most important event type is [`Event::Input`].
//! You don't need to handle all events, it's fine to ignore events that are not relevant to your node.
//!
//! The event stream will close itself after a [`Event::Stop`] was received.
//! A manual `break` on [`Event::Stop`] is typically not needed.
//! _(You probably do need to use a manual `break` on stop events when using the
//! [`StreamExt::merge`][`futures_concurrency::stream::StreamExt::merge`] implementation on
//! [`EventStream`] to combine the stream with an external one.)_
//!
//! Once the event stream finished, nodes should exit.
//! Note that Dora kills nodes that don't exit quickly after a [`Event::Stop`] of type
//! [`StopCause::Manual`] was received.
//!
//!
//!
//! ## Dynamic Nodes
//!
//! <div class="warning">
//!
//! Dynamic nodes have certain [limitations](#limitations). Use with care.
//!
//! </div>
//!
//! Nodes can be defined as `dynamic` by setting their `path` attribute to `dynamic` in the
//! dataflow YAML file. Dynamic nodes are not spawned by the Dora framework and need to be started
//! manually.
//!
//! Dynamic nodes cannot use the [`DoraNode::init_from_env`] function for initialization.
//! Instead, they can be initialized through the [`DoraNode::init_from_node_id`] function.
//!
//! ### Limitations
//!
//! - Dynamic nodes **don't work with `dora run`**.
//! - As dynamic nodes are identified by their node ID, this **ID must be unique**
//! across all running dataflows.
//! - For distributed dataflows, nodes need to be manually spawned on the correct machine.
//!
//!
//! ## Node Integration Testing
//!
//! Dora provides built-in support for integration testing of nodes. See the [integration_testing]
//! module for details.
/// Apache Arrow 59, dora's current **internal** major.
///
/// Enabled by the `arrow-v59` feature, which pulls no extra dependency: this
/// is the same copy of Arrow 59 dora itself links, so
/// [`DoraArray::as_array`] hands it back for free and arrays built with it
/// need no conversion.
///
/// This is deliberately not `pub use arrow;`. A bare `arrow` re-export changes
/// meaning silently when dora bumps its internal major; `arrow_v59` either
/// exists and means Arrow 59, or it is visibly gone. See
/// `docs/plan-arrow-version-decoupling.md`.
pub use arrow as arrow_v59;
/// Apache Arrow 58, for nodes that name that major.
///
/// Enabled by the `arrow-v58` feature. Arrow 58 is **not** dora's internal
/// major, so payloads cross a C Data Interface hop, exposed as `TryFrom`
/// impls in both directions (`DoraArray::try_from(&arr as &dyn arrow58 Array)`
/// and `arrow_v58::array::ArrayRef::try_from(&dora)`). The hop is fallible —
/// hence `TryFrom` and not `From` — but does not copy buffers.
pub use arrow58 as arrow_v58;
// Deliberately *not* a glob re-export: `dora_arrow_convert::internal` is an
// Arrow-typed, semver-exempt seam for dora's own crates and must not become
// reachable through the frozen `dora-node-api` surface.
pub use ;
pub use uhlc;
/// The subset of [`dora_core`] that is part of dora's public API.
///
/// Deliberately not `pub use dora_core::self`. Re-exporting the whole crate
/// froze `dora_core`'s descriptor, topics, build, manifest and type-registry
/// surface into dora's 1.0 guarantee, none of which a node needs — the only
/// items reached through this path anywhere are the three id types below and
/// `uhlc`, which is re-exported at the crate root.
///
/// The `config` path is preserved verbatim because
/// `dora_node_api::dora_core::config::DataId` is what `dora new` scaffolds and
/// what the Rust API reference documents.
pub use ;
use ;
pub use ;
pub use futures;
pub use init_tracing;
pub use ;
pub use uuid;
pub use serde_json;
use oneshot;
/// Asynchronous event stream and daemon communication.
pub use ;
/// Backward-compatible alias for [`Event`], so code using the old `DoraEvent`
/// name still compiles.
pub use Event as DoraEvent;