Skip to content

Commit

Permalink
#30 Dataflow model guide is ported from cpp.react (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
YarikTH committed Jul 3, 2021
1 parent 748cfb7 commit 5588d31
Show file tree
Hide file tree
Showing 4 changed files with 992 additions and 0 deletions.
80 changes: 80 additions & 0 deletions doc/dataflow_model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Dataflow model

Disclaimer: based on [Dataflow model guide from cpp.react](http://snakster.github.io/cpp.react/guides/Dataflow-model.html)

* [Graph model](#graph-model)
* [Input and output nodes](#input-and-output-nodes)
* [Static and dynamic nodes](#static-and-dynamic-nodes)
* [Domains](#domains)
* [Cycles](#cycles)
* [Propagation model](#propagation-model)
* [Transactions](#transactions)
* [Properties](#properties)
* [Conclusions](#conclusions)

## Graph model

The dataflow between reactive values can be modeled (and visualized) as a [directed acyclic graph (DAG)](https://en.wikipedia.org/wiki/Directed_acyclic_graph).
Such a graph can be constructed from the dependency relations; each entity is a node and directed edges denote data propagation paths.

To give an example, let `a`, `b` and `c` be arbitrary signals.
`x` is another signal that is calculated based on the former.
Instead of invoking `make_signal` explicitly, the overloaded `+` operator is used to achieve the same result.

```cpp
ureact::signal<S> x = (a + b) + c;
```

This is the matching dataflow graph:

<p align="left"><img src="../support/data/signals_1.svg"></p>

From a dataflow perspective, what kind of data is propagated and what exactly happens to it in each node is not relevant.

µReact does not expose the graph data structures directly to the user; instead, they are wrapped by lightweight proxies.
Such a proxy is essentially a shared pointer to the heap-allocated node.
Examples of proxy types are `signal`, `observer`.
The concrete type of the node is hidden behind the proxy.

We show this scheme for the previous example:

```cpp
ureact::signal<S> a = make_var(...);
ureact::signal<S> b = make_var(...);
ureact::signal<S> c = make_var(...);
ureact::signal<S> x = (a + b) + c;
```

The `make_var` function allocates the respective node and links it to the returned proxy.
Not all nodes in the graph are bound to a proxy; the temporary sub-expression `a + b` results in a node as well.
If a new node is created, it takes shared ownership of its dependencies, because it needs them to calculate its own value.
This prevents the `a + b` node from disappearing.

The resulting reference graph is similar to the dataflow graph, but with reverse edges (and as such, a DAG as well):

<p align="left"><img src="../support/data/signals_2.svg"></p>

The number inside each node denotes its reference count. On the left are the proxy instances exposed by the API.
Assuming the proxies for `a`, `b` and `c` would go out of scope, but `x` remains, the reference count of all nodes is still 1, until `x` disappears as well.
Once that happens, the graph is deconstructed from the bottom up.


### Input and output nodes

### Static and dynamic nodes

### Domains

### Cycles

## Propagation model

### Transactions

### Properties

## Conclusions

---------------

[Home](readme.md#reference)
1 change: 1 addition & 0 deletions doc/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ Usage:
* [Tutorial](tutorial.md) - make sure you have read it before the other parts of the documentation
-->
* [Signals vs callbacks](signals_vs_callbacks.md)
* [Dataflow model](dataflow_model.md)
* [Integration](../tests/integration/) - how to get and link this library
* [Examples](../tests/src/examples)
Loading

0 comments on commit 5588d31

Please sign in to comment.