mirror of
https://github.com/fluencelabs/aqua-book
synced 2024-12-04 15:20:19 +00:00
GitBook: [master] 3 pages modified
This commit is contained in:
parent
f6d737e844
commit
50feadbee3
@ -1,6 +1,2 @@
|
||||
# Execution flow
|
||||
|
||||
Aqua's main goal is to express how the execution flows: moves from peer to peer, forks to parallel flows and then joins back, uses data from one step in another.
|
||||
|
||||
As the foundation of Aqua is based on π-calculus, finally flow is decomposed into sequential \(seq, .\), conditional \(xor, ^\), parallel \(par, \|\) computations and iterations based on data \(!P\).
|
||||
|
||||
|
@ -10,17 +10,7 @@ If any branch is executed successfully, the flow execution continues.
|
||||
|
||||
All the data defined in parallel branches is available in the subsequent code.
|
||||
|
||||
### Parallel operations
|
||||
|
||||
As of time of writing, there's only one parallel expression: `par`
|
||||
|
||||
Its syntax is derived from π-calculus notation of parallelism: `A | B`
|
||||
|
||||
```text
|
||||
-- foo and bar will be executed in parallel, if possible
|
||||
foo()
|
||||
par bar()
|
||||
```
|
||||
### Implementation limitation
|
||||
|
||||
Parallel execution has some implementation limitations:
|
||||
|
||||
@ -28,9 +18,61 @@ Parallel execution has some implementation limitations:
|
||||
* No parallelism when executing a script on single peer \(fix planned\)
|
||||
* No concurrency in services: one service instance does only one job in a time. Keep services small \(wasm limitation\)
|
||||
|
||||
We might overcome these limitations later, but for now, plan your application design having this in mind.
|
||||
|
||||
### Parallel operations
|
||||
|
||||
### par
|
||||
|
||||
`par` syntax is derived from π-calculus notation of parallelism: `A | B`
|
||||
|
||||
```text
|
||||
-- foo and bar will be executed in parallel, if possible
|
||||
foo()
|
||||
par bar()
|
||||
|
||||
-- It's useful to combine `par` with `on` block,
|
||||
-- to delegate further execution to different peers.
|
||||
|
||||
-- In this case execution will continue on two peers, independently
|
||||
on "peer 1":
|
||||
x <- foo()
|
||||
par on "peer 2":
|
||||
y <- bar()
|
||||
|
||||
-- Once any of the previous functions return x or y,
|
||||
-- execution continues. We don't know the order, so
|
||||
-- if y is returned first, hello(x) will not execute
|
||||
hello(x)
|
||||
hello(y)
|
||||
|
||||
-- You can fix it with par
|
||||
-- What's comes faster, will advance the execution flow
|
||||
hello(x)
|
||||
par hello(y)
|
||||
```
|
||||
|
||||
`par` works in infix manner between the previously stated function and the next one.
|
||||
|
||||
#### co
|
||||
|
||||
`co` , short for `coroutine`, prefixes an operation to send it to background. From π-calculus perspective, it's the same as `A | null`, where `null`-process is the one that does nothing and completes instantly.
|
||||
|
||||
```text
|
||||
-- Let's send foo to background and continue
|
||||
co foo()
|
||||
|
||||
-- Do something on another peer, not blocking the flow on this one
|
||||
co on "some peer":
|
||||
baz()
|
||||
|
||||
-- This foo does not wait for baz()
|
||||
foo()
|
||||
```
|
||||
|
||||
### Join behavior
|
||||
|
||||
Join means that data was created by different parallel execution flows and then used on a single peer to perform computations.
|
||||
Join means that data was created by different parallel execution flows and then used on a single peer to perform computations. It works the same way for any parallel blocks, be it `par`, `co` or something else \(`for par`\).
|
||||
|
||||
In Aqua, you can refer to previously defined variables. In case of sequential computations, they are available, if execution not failed:
|
||||
|
||||
|
@ -1,64 +1,4 @@
|
||||
# Sequential
|
||||
|
||||
By default, Aqua code is executed line by line, sequentially.
|
||||
|
||||
### Contract
|
||||
|
||||
Data from the first branch is available in the second branch.
|
||||
|
||||
Second branch is executed iff the first branch succeeded.
|
||||
|
||||
If any branch errored, then the whole sequence is errored.
|
||||
|
||||
If all branches executed successfully, then the whole seq is executed successfully.
|
||||
|
||||
### Sequential operations
|
||||
|
||||
#### call arrow
|
||||
|
||||
Any runnable piece of code in Aqua is an arrow from its domain to codomain.
|
||||
|
||||
```text
|
||||
-- Call a function
|
||||
foo()
|
||||
|
||||
-- Call a function that returns smth, assign results to a variable
|
||||
x <- foo()
|
||||
|
||||
-- Call an ability function
|
||||
y <- Peer.identify()
|
||||
|
||||
-- Pass an argument
|
||||
z <- Op.identity(y)
|
||||
```
|
||||
|
||||
When you write `<-`, this means not just "assign results of the function on the right to variable on the left". It means that all the effects are executed: [service](../abilities-and-services.md) may change state, [topology](../topology.md) may be shifted. But you end up in the same topological scope.
|
||||
|
||||
#### on
|
||||
|
||||
`on` denotes the peer where the code must be executed.
|
||||
|
||||
```text
|
||||
func foo():
|
||||
-- Will be executed where `foo` was executed
|
||||
bar()
|
||||
|
||||
-- Move to another peer
|
||||
on another_peer:
|
||||
-- To call bar, we need to leave the peer where we were and get to another_peer
|
||||
-- It's done automagically
|
||||
bar()
|
||||
|
||||
on third_peer via relay:
|
||||
-- This is executed on third_peer
|
||||
-- But we denote that to get to third_peer and to leave third_peer
|
||||
-- an additional hop is needed: get to relay, then to peer
|
||||
bar()
|
||||
|
||||
-- Will be executed in the `foo` call site again
|
||||
-- To get from the previous `bar`, compiler will add a hop to relay
|
||||
bar()
|
||||
```
|
||||
|
||||
See more in [Topology](../topology.md) section.
|
||||
Sequential
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user