GitBook: [docs] 6 pages and 10 assets modified
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
@ -183,7 +183,9 @@ Particle id: 5fb0af87-310f-4b12-8c73-e044cfd8ef6e. Waiting for results... Press
|
||||
|
||||
And we are golden. Give it some time and start checking Ethqlite for latest block and reward info!!
|
||||
|
||||
TODO: this isn't working since we can't upload a key with the script.
|
||||
{% hint style="info" %}
|
||||
Unfortunately, our daemonized service won't work just yet as the current implementation cannot take the \(client\) seed we need in order to get our SQLite write working. It's on the to-do list but if you need it, please contact us and we'll see about juggling priorities.
|
||||
{% endhint %}
|
||||
|
||||
For completeness sake, let's remove the stored service with the following AIR script:
|
||||
|
||||
@ -192,8 +194,6 @@ For completeness sake, let's remove the stored service with the following AIR sc
|
||||
(call node ("script" "remove") [script_id] result)
|
||||
```
|
||||
|
||||
TODO: finalize or delete for now.
|
||||
|
||||
## Advanced Service Output Access
|
||||
|
||||
As Aquamarine advances a particle's journey through the network, output from a service at workflow sequence s-1 method tends to be the input for a service at sequence s method. For example, the _hex\_to\_int_ method, as used earlier, takes the output from the _get\_latest\_block_ method. With single parameter outputs, this is a pretty straight forward and inherently decoupled dependency relation. However, when result parameters become more complex, such as structs, we still would like to keep services as decoupled as possible.
|
||||
|
@ -51,7 +51,7 @@ pub fn greeting(name: String) -> String {
|
||||
|
||||
Let's go line by line:
|
||||
|
||||
1. Import the [fce](https://github.com/fluencelabs/fce/tree/5effdcba7215cd378f138ab77f27016024720c0e) module from the [Fluence crate](https://crates.io/crates/fluence), which allows us to compile our code to the [wamser32-wasi](https://docs.rs/crate/wasi/0.6.0) target
|
||||
1. Import the [fce](https://github.com/fluencelabs/fce/tree/5effdcba7215cd378f138ab77f27016024720c0e) module from the [Fluence crate](https://crates.io/crates/fluence), which allows us to compile our code to the [wasm32-wasi](https://docs.rs/crate/wasi/0.6.0) target
|
||||
|
||||
2. Import the [module\_manifest](https://github.com/fluencelabs/rust-sdk/blob/master/crates/main/src/module_manifest.rs), which allows us to embed the SDK version in our module
|
||||
|
||||
|
@ -23,7 +23,7 @@ AIR instructions are intended to launch the execution of a service method as fol
|
||||
4. The arguments specified by the argument list are passed to the method
|
||||
5. The result of the method returned under the name output name
|
||||
|
||||
**Figure 2: Sequential Instruction** ![Execution](../../.gitbook/assets/air_sequential_2%20%281%29%20%281%29%20%281%29.png)
|
||||
**Figure 2: Sequential Instruction** ![Execution](../../.gitbook/assets/air_sequential_2%20%281%29%20%281%29%20%281%29%20%281%29.png)
|
||||
|
||||
The _**seq**_ instruction takes two instructions at most as its arguments and executes them sequentially, one after the other.
|
||||
|
||||
@ -33,7 +33,7 @@ The _**par**_ instruction takes two instructions at most as its arguments and pa
|
||||
|
||||
TODO: add better graphic showing the disticntion of branching vs seq.
|
||||
|
||||
**Figure 4: Fold Instruction** ![Execution](../../.gitbook/assets/air_fold_4%20%281%29%20%281%29.png)
|
||||
**Figure 4: Fold Instruction** ![Execution](../../.gitbook/assets/air_fold_4%20%281%29%20%282%29%20%281%29.png)
|
||||
|
||||
The _**fold**_ instruction iterates over the elements of an array and workds as follows:
|
||||
|
||||
@ -49,7 +49,7 @@ This instruction is intended for organizing branches in the flow of execution as
|
||||
* The first instruction is executed and if the execution is successful, then the second instruction is ignored
|
||||
* If the first instruction fails, then the second one is executed.
|
||||
|
||||
**Figure 6: Null Instruction** ![Execution](../../.gitbook/assets/air_null_6%20%281%29.png)
|
||||
**Figure 6: Null Instruction** ![Execution](../../.gitbook/assets/air_null_6%20%281%29%20%282%29.png)
|
||||
|
||||
This is an empty instruction: it takes no arguments and does nothing. The _**null**_ instruction is useful for generating code.
|
||||
|
||||
|
@ -16,7 +16,7 @@ Please note that the [`fldist`](../knowledge_tools.md#fluence-proto-distributor-
|
||||
|
||||
## API
|
||||
|
||||
### peer is_connected
|
||||
### peer is\_connected
|
||||
|
||||
Checks if there is a direct connection to the peer identified by a given PeerId
|
||||
|
||||
@ -45,10 +45,10 @@ Example of a service call:
|
||||
(seq
|
||||
(call node ("op" "identity") ["/ip4/1.2.3.4/tcp/7777" "/ip4/1.2.3.4/tcp/9999"] addrs)
|
||||
(call node ("peer" "connect") ["123D..." addrs] ok)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### peer get_contact
|
||||
### peer get\_contact
|
||||
|
||||
Resolves the contact of a peer via [Kademlia](https://en.wikipedia.org/wiki/Kademlia)
|
||||
|
||||
@ -64,30 +64,30 @@ Contact {
|
||||
}
|
||||
```
|
||||
|
||||
Example of a service call:
|
||||
Example of a service call:
|
||||
|
||||
```scheme
|
||||
(call node ("peer" "get_contact") ["123D..."] contact)
|
||||
```
|
||||
|
||||
#### peer identify
|
||||
#### peer identify
|
||||
|
||||
Get information about the peer
|
||||
|
||||
* **Arguments**: None
|
||||
* **Returns:** _external address_
|
||||
|
||||
```json
|
||||
```javascript
|
||||
{ "external_addresses": [ "/ip4/1.2.3.4/tcp/7777", "/dns4/stage.fluence.dev/tcp/19002" ] }
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
Example of service call:
|
||||
|
||||
```scheme
|
||||
(call node ("peer" "identify") [] info) peer timestamp_ms
|
||||
(call node ("peer" "identify") [] info) peer timestamp_ms
|
||||
```
|
||||
|
||||
### peer timestamp_ms
|
||||
### peer timestamp\_ms
|
||||
|
||||
Get Unix timestamp in milliseconds
|
||||
|
||||
@ -100,7 +100,7 @@ Example of service call:
|
||||
(call node ("peer" "timestamp_ms") [] ts_ms)
|
||||
```
|
||||
|
||||
### peer timestamp_sec
|
||||
### peer timestamp\_sec
|
||||
|
||||
Get Unix timestamp in seconds
|
||||
|
||||
@ -152,10 +152,10 @@ Used to enumerate services deployed to a peer.
|
||||
Example of service call:
|
||||
|
||||
```scheme
|
||||
(call node ("srv" "list") [] services)
|
||||
(call node ("srv" "list") [] services)
|
||||
```
|
||||
|
||||
### srv add_alias
|
||||
### srv add\_alias
|
||||
|
||||
Adds an alias on service, so service could be called not only by service\_id but by alias.
|
||||
|
||||
@ -168,9 +168,7 @@ Example of service call:
|
||||
(call node ("srv" "add_alias") [alias service_id])
|
||||
```
|
||||
|
||||
|
||||
|
||||
### srv get_interface
|
||||
### srv get\_interface
|
||||
|
||||
Retrieves the functional interface of a service running on the node specified in the service call.
|
||||
|
||||
@ -185,22 +183,22 @@ Retrieves the functional interface of a service running on the node specified in
|
||||
}
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
Example of service call:
|
||||
|
||||
```scheme
|
||||
(call node ("srv" "get_interface") [service_id] interface)
|
||||
(call node ("srv" "get_interface") [service_id] interface)
|
||||
```
|
||||
|
||||
### dist add_module
|
||||
### dist add\_module
|
||||
|
||||
Used to add modules to the node specified in the service call.
|
||||
|
||||
* Arguments:
|
||||
* Arguments:
|
||||
|
||||
* bytes – a base64 string containing the .wasm module to add.
|
||||
* config – an object of the following structure
|
||||
|
||||
```json
|
||||
```javascript
|
||||
{
|
||||
"name": "my_module_name"
|
||||
}
|
||||
@ -212,14 +210,14 @@ Example of service call:
|
||||
(call node ("dist" "add_module") [bytes config] hash)
|
||||
```
|
||||
|
||||
### dist list_modules
|
||||
### dist list\_modules
|
||||
|
||||
Get a list of modules available on the node
|
||||
|
||||
* Arguments: None
|
||||
* Returns: an array of objects containing module descriptions
|
||||
|
||||
```json
|
||||
```javascript
|
||||
[
|
||||
{
|
||||
"name": "moduleA",
|
||||
@ -232,10 +230,10 @@ Get a list of modules available on the node
|
||||
Example of service call:
|
||||
|
||||
```scheme
|
||||
(call node ("dist" "list_modules") [] modules)
|
||||
(call node ("dist" "list_modules") [] modules)
|
||||
```
|
||||
|
||||
### dist get_module_interface
|
||||
### dist get\_module\_interface
|
||||
|
||||
Get the interface of a module
|
||||
|
||||
@ -243,7 +241,7 @@ Get the interface of a module
|
||||
* Returns: an interface of the module \( see _srv get\_interface \)_ mple of service call:
|
||||
|
||||
```scheme
|
||||
(call node ("dist" "get_interface") [hash] interface)
|
||||
(call node ("dist" "get_interface") [hash] interface)
|
||||
```
|
||||
|
||||
### dist add\_blueprint
|
||||
@ -252,38 +250,40 @@ Used to add a blueprint to the node specified in the service call.
|
||||
|
||||
* Arguments: blueprint – an object of the following structure
|
||||
|
||||
```json
|
||||
```javascript
|
||||
{
|
||||
"name": "good_service",
|
||||
"dependencies": [ "hash:6ebff28c...", "hash:1e59875a...", "hash:d164a07..." ]
|
||||
}
|
||||
```
|
||||
|
||||
Where module dependencies are specified as [_blake3_](https://crates.io/crates/blake3) hashes of modules
|
||||
```text
|
||||
Where module dependencies are specified as [_blake3_](https://crates.io/crates/blake3) hashes of modules
|
||||
```
|
||||
|
||||
* Returns: Generated blueprint id
|
||||
|
||||
Example of service call:
|
||||
|
||||
```scheme
|
||||
(call node ("dist" "add_blueprint") [blueprint] blueprint_id)
|
||||
(call node ("dist" "add_blueprint") [blueprint] blueprint_id)
|
||||
```
|
||||
|
||||
### dist list\_blueprints
|
||||
|
||||
Used to get the blueprints available on the node specified in the service call.
|
||||
Used to get the blueprints available on the node specified in the service call.
|
||||
|
||||
* Arguments: None
|
||||
* Returns: an array of blueprint structures.
|
||||
|
||||
A blueprint is an object of the following structure:
|
||||
|
||||
```json
|
||||
```javascript
|
||||
{
|
||||
"id": "uuid-1234-...",
|
||||
"name": "good_service",
|
||||
"dependencies": [ "hash:6ebff28c...", "hash:1e59875a...", "hash:d164a07..." ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
@ -292,7 +292,7 @@ Example of service call:
|
||||
(call node ("dist" "list_blueprints") [] blueprints)
|
||||
```
|
||||
|
||||
#### script add
|
||||
#### script add
|
||||
|
||||
Adds a given script to a node. That script will be called with a fixed interval with the default setting at approx. three \(3\) seconds.
|
||||
|
||||
@ -303,18 +303,18 @@ Recurring scripts can't read variables from data, they must be literal. That mea
|
||||
* _interval_ – an optional string containing interval in seconds. If set, the script will be executed periodically at that interval. If omitted, the script will be executed only once. All intervals are rounded to 3 seconds. The minimum interval is 3 seconds.
|
||||
* Returns: uuid – script id that can be used to remove that script
|
||||
|
||||
Example of service call:
|
||||
Example of service call:
|
||||
|
||||
* Without an interval parameter value, the script executes once:
|
||||
|
||||
```
|
||||
(call node ("script" "add") [script] id)
|
||||
```text
|
||||
(call node ("script" "add") [script] id)
|
||||
```
|
||||
|
||||
* With an interval parameter value _k_ passed as a string, the script executes every _k_ seconds \(21 in this case\)
|
||||
|
||||
```scheme
|
||||
(call node ("script" "add") [script "21"] id)
|
||||
(call node ("script" "add") [script "21"] id)
|
||||
```
|
||||
|
||||
### script remove
|
||||
@ -327,7 +327,7 @@ Removes recurring script from a node. Only a creator of the script can delete it
|
||||
Example of service call:
|
||||
|
||||
```scheme
|
||||
(call node ("script" "remove") [script_id] result)
|
||||
(call node ("script" "remove") [script_id] result)
|
||||
```
|
||||
|
||||
### script list
|
||||
@ -335,7 +335,7 @@ Example of service call:
|
||||
* Arguments: None
|
||||
* Returns: A list of existing scripts on the node. Each object in the list is of the following structure:
|
||||
|
||||
```json
|
||||
```javascript
|
||||
{
|
||||
"id": "uuid-1234-...",
|
||||
"src": "(seq (call ...", //
|
||||
@ -345,7 +345,7 @@ Example of service call:
|
||||
}
|
||||
```
|
||||
|
||||
Example of a service call:
|
||||
Example of a service call:
|
||||
|
||||
```scheme
|
||||
(call node ("script" "list") [] list)
|
||||
@ -358,41 +358,39 @@ Acts as an identity function. This service returns exactly what was passed to it
|
||||
Example of service call:
|
||||
|
||||
```scheme
|
||||
(call node ("op" "identity") [args] result)
|
||||
(call node ("op" "identity") [args] result)
|
||||
```
|
||||
|
||||
### deprecated add_provider
|
||||
### deprecated add\_provider
|
||||
|
||||
Used in service aliasing. ****Stores the specified service provider \(provider\) in the internal storage of the node indicated in the service call and associates it with the given key \(key\). After executing add\_provider, the provider can be accessed via the get\_providers service using this key.
|
||||
Used in service aliasing. _\*\*_Stores the specified service provider \(provider\) in the internal storage of the node indicated in the service call and associates it with the given key \(key\). After executing add\_provider, the provider can be accessed via the get\_providers service using this key.
|
||||
|
||||
* Arguments:
|
||||
|
||||
* key – a string; usually, it is a human-readable service alias.
|
||||
* provider – the location of the service. It is an object of the following structure:
|
||||
|
||||
```json
|
||||
```javascript
|
||||
{
|
||||
"peer": "123D...", // PeerId of some peer in the network
|
||||
"service_id": "uuid-1234-..." // Optional service_id of the service running on the peer specified by peer
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
|
||||
```scheme
|
||||
(call node ("deprecated" "add_provider") [key provider])
|
||||
(call node ("deprecated" "add_provider") [key provider])
|
||||
```
|
||||
|
||||
|
||||
|
||||
### deprecated get_providers
|
||||
### deprecated get\_providers
|
||||
|
||||
Used in service aliasing to retrieve providers for a given key.
|
||||
|
||||
* Arguments: _key_ – a string; usually, it is a human-readable service alias.
|
||||
* Returns: an array of objects of the following structure:
|
||||
|
||||
```json
|
||||
```javascript
|
||||
{
|
||||
"peer": "123D...", // required field
|
||||
"service_id": "uuid-1234-..." // optional field
|
||||
@ -404,3 +402,4 @@ Example of service call:
|
||||
```scheme
|
||||
(call node ("deprecated" "get_providers") [key] providers)
|
||||
```
|
||||
|
||||
|
@ -6,29 +6,36 @@ The [Fluence Dashboard](https://dash.fluence.dev/) facilitates the discovery of
|
||||
|
||||
In order to execute the cUrl service and collect the result, i.e., response, we call upon our composition and coordination medium Aquamarine via an Aquamarine Intermediate Representation \(AIR\) script.
|
||||
|
||||
```text
|
||||
```scheme
|
||||
;; handle possible errors via xor
|
||||
(xor
|
||||
(seq
|
||||
;; call function 'service_id.request' on node 'relay'
|
||||
(call relay (service_id "request") [url] result)
|
||||
|
||||
;; return result back to the client
|
||||
(call %init_peer_id% (returnService "run") [result])
|
||||
)
|
||||
;; if error, return it to the client
|
||||
(call %init_peer_id% (returnService "run") [%last_error%])
|
||||
)
|
||||
```
|
||||
|
||||
Without going too deep into Aquamarine and AIR, this script specifies that we call a public peer-to-peer relay \(node\) on the network, ask to run the \(curl\) _request_ function with data parameter _url_ and _service\_id_ parameter, and collect the _result_ **xor** the _error message_ in case of execution failure. We also promise to pass the _service\_id_ and _url_ parameters to the scripts. The "magic" happens by handing the script to the `fldist` CLI tool, which then sends the script for execution to the specified p2p network and locally shadows the execution. Please note that Instead of developing full-fledged frontend applications, we use the `fldist` CLI tool. However, a [JS SDK](https://github.com/fluencelabs/fluence-js) is available to accelerate the development of more complex frontend applications.
|
||||
Without going too deep into Aquamarine and AIR, this script specifies that we call a public peer-to-peer relay \(node\) on the network, ask to run the \(curl\) _request_ function with data parameter _url_ and _service\_id_ parameter, and collect the _result_ **xor** the _error message_ in case of execution failure. We also promise to pass the _service\_id_ and _url_ parameters to the scripts.
|
||||
|
||||
The "magic" happens by handing the script to the `fldist` CLI tool, which then sends the script for execution to the specified p2p network and locally shadows the execution. Please note that Instead of developing full-fledged frontend applications, we use the `fldist` CLI tool. However, a [JS SDK](https://github.com/fluencelabs/fluence-js) is available to accelerate the development of more complex frontend applications.
|
||||
|
||||
{% hint style="info" %}
|
||||
Throughout the document, we utilize service and node ids, which in most cases may be different for you.
|
||||
{% endhint %}
|
||||
|
||||
With the service id parameter obtained from the dashboard lookup above, e.g., "f92ce98b-1ed6-4ce3-9864-11f4e93a478f", and some Fluence goodness at both the local and remote levels enables us to:
|
||||
With the service id parameter obtained from the dashboard lookup above, e.g., `"f92ce98b-1ed6-4ce3-9864-11f4e93a478f"`, and some Fluence goodness at both the local and remote levels enables us to:
|
||||
|
||||
1. find the p2p node hosting the curl service with above service id ,
|
||||
2. execute the service and
|
||||
3. collect the response
|
||||
|
||||
In your directory of choice, save the above script as _curl\_request.clj_ and run:
|
||||
In your directory of choice, save the above script as `curl_request.clj` and run:
|
||||
|
||||
```bash
|
||||
$ fldist run_air -p curl_request.clj -d '{"service_id": "f92ce98b-1ed6-4ce3-9864-11f4e93a478f", "url":"https://api.duckduckgo.com/?q=homotopy&format=json"}'
|
||||
@ -75,7 +82,7 @@ To recap, we:
|
||||
* executed the \(remote\) curl service request, and
|
||||
* collected the result
|
||||
|
||||
With essentially a two line script and a couple of parameters we executed a search request as a service on a peer-to-peer network. Even this small example should impress the ease afforded by Aquamarine to compose applications from portable, reusable and distributed services not only taken serverless to the next level by greatly reducing devops requirements but also empowering developers with a composition and coordination medium second to none.
|
||||
With essentially a two-line script and a couple of parameters, we executed a search request as a service on a peer-to-peer network. Even this small example should impress the ease afforded by Aquamarine to compose applications from portable, reusable and distributed services not only taken serverless to the next level by greatly reducing devops requirements but also empowering developers with a composition and coordination medium second to none.
|
||||
|
||||
In the next section, we build an Ethereum block getter application by coordinating multiple services into an application.
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
# Research, Papers And References
|
||||
|
||||
Coming soon. If you really need this section, contact us through any of the social media channels or Github.
|
||||
* [Fluence Manifesto](https://fluence.network/manifesto.html)
|
||||
* [Fluence Protocol](https://github.com/fluencelabs/rfcs/blob/main/0-overview.md)
|
||||
|
||||
|
||||
|
||||
|