-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(docs): Event handling in JS #96
base: main
Are you sure you want to change the base?
Changes from all commits
a44d784
b470c64
06fa289
47f0b75
475b1d5
11b845c
df4e645
b97e9ef
9b4732f
739f191
faaea76
bb2566a
bcca708
ac3a8e4
96fcbe3
d64b75a
416b53d
7135029
4b3bb05
65638b9
bbfca9f
45925e0
847e2de
dd13848
5200024
30c5ae0
1b2f2d2
2026c9c
5775cbc
b3aba37
b0161fd
f184a98
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,112 @@ | ||||||
# Introduction | ||||||
|
||||||
> Make sure you've read ***Getting Started*** and ***Quickstart*** pages. | ||||||
|
||||||
Fluence Cloud Functions are hosted on distributed peers in the Fluence network waiting to be called. That is, your functions need to be triggered in order to do some work. Event triggers may arise from a multitude of sources ranging from browser click-events to changes in a database column. Regardless of the source, the event needs to trigger the function(s) which, as you already know from the introduction and quickstart chapters, requires Aqua to orchestrate the invocation of your distributed compute function(s). | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
One way of triggering the orchestration of your function(s) is interactively with the Fluence CLI: `fluence run -f 'your function(args)'`. However, events may require (near) real-time processing which in turn requires the orchestration of your function(s) immediately after the event occurred. Whether this is in the browser or some other application, we need to trigger the appropriate Aqua script from a (embedded) client peer. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd recommend not to use the excessive braces like that. There's no semantic advantages in hinting at alternatives (like singular/plural), or may even mislead, but extra syntactic elements get in the way when reading. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to ask @boneyard93501 is there any specific meaning in these braces. |
||||||
|
||||||
The [js-client](https://github.com/fluencelabs/js-client) provides this functionality and can be used in your frontend web app or nodejs application to provide the connection to the Fluence network via a relay peer. See Figure 1. | ||||||
|
||||||
Figure 1: Using js-client to trigger compute function | ||||||
mermaid | ||||||
```mermaid | ||||||
sequenceDiagram | ||||||
|
||||||
box Application | ||||||
participant A as Application | ||||||
participant C as Client Peer | ||||||
end | ||||||
|
||||||
box Network | ||||||
participant R as Relay | ||||||
participant Pk as Peer k | ||||||
end | ||||||
|
||||||
A ->> A: event capture | ||||||
A ->> C: event trigger with embedded js-client | ||||||
C ->> R: Aqua script choreography dispatch | ||||||
R ->> Pk: compute function invocation | ||||||
``` | ||||||
|
||||||
## Interaction with deployed services | ||||||
|
||||||
### Motivation | ||||||
Imagine you've deployed your services to Fluence Network and now wondering how to interact with them, e.g., call Aqua function. | ||||||
|
||||||
Let's forget about CLI for a minute because CLI relies on the described below event handling process. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
To interact with peers of Fluence network, i.e., to execute an Aqua functions, the "client" has to be a peer. | ||||||
Such client peers don't have to be publicly accessible or long-running in nature, but they need to follow the protocol. | ||||||
|
||||||
For this reason, Fluence provides thin and simple client peer for interacting with Fluence network - JS client. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Client peer could be JS or Python or could be written in any other language |
||||||
Actually, FCLI relies on JS client when interacts with Fluence Network by executing Aqua functions. | ||||||
The client is dedicated to JavaScript ecosystems. | ||||||
It works seamlessly in browser, Node.js and other JS environments. | ||||||
|
||||||
It's a perfect fit for JS projects because the client is easy to install and manage. | ||||||
|
||||||
Moreover, client have additional unique features, which extend Fluence protocol. | ||||||
|
||||||
- Host services locally in contrast with the hosting logic remotely on peers in Fluence Network. | ||||||
- Send and receive Fluence network events | ||||||
- Exchange events between multiple JS clients. | ||||||
|
||||||
### Specification | ||||||
|
||||||
`js-client` easily embeds into any frontend or Node.js application to invoke remote compute functions. For example, your Node.js application maybe processing sensor inputs on an IoT device or scan a database for changes. See Figure 2. | ||||||
|
||||||
Figure 2: Triggering Compute Functions with js-client | ||||||
```mermaid | ||||||
sequenceDiagram | ||||||
|
||||||
participant E as Environment | ||||||
participant A as nodejs app with embedded js-client | ||||||
participant C as app's client peer | ||||||
participant N as Fluence Network | ||||||
|
||||||
E ->> A: new data event | ||||||
A ->> C: create client peer | ||||||
C ->> N: choreograph the invocation of compute function(s) | ||||||
``` | ||||||
|
||||||
## Exchanging events between clients | ||||||
|
||||||
Let's imagine that we're building a secret chat app atop Fluence Network | ||||||
Chat is secret because messages aren't stored anywhere. | ||||||
|
||||||
The Chat app consists of minimum two peers or JS clients connected to Fluence network. | ||||||
Each JS client is running in the browser because that's where the app is. | ||||||
JS client uses the **relay** as a proxy to Fluence network because direct connection is not always possible due to network limitation, e.g., provider allows connection to a limited set of IP addresses. | ||||||
Publicly accessible relays (in contract with regular Fluence peers, which could be publicly inaccessible) allow the chat participants to communicate with each other from any location. | ||||||
Fluence network acknowledged about connected peers via relays and events could be passed forth and back. More peers could be involved in this communication. | ||||||
|
||||||
Let's check the figure 3 and review the possible interactions between two participants in the chat. | ||||||
|
||||||
Figure 3: Secret chat interaction diagram | ||||||
```mermaid | ||||||
sequenceDiagram | ||||||
box Alice's Application | ||||||
participant A1 as Alice | ||||||
participant C1 as Alice's Client Peer | ||||||
end | ||||||
|
||||||
box Network | ||||||
participant R1 as Alice's Relay | ||||||
participant R2 as Bob's Relay | ||||||
participant Pk as Peer k | ||||||
end | ||||||
|
||||||
A1 ->> A1: event capture (Alice sends the message) | ||||||
A1 ->> C1: event trigger with embedded js-client | ||||||
C1 ->> R1: Aqua script choreography dispatch | ||||||
R1 ->> Pk: compute function invocation | ||||||
Pk ->> R2: compute function invocation | ||||||
R2 ->> R2: event dispatched to Bob's JS client | ||||||
``` | ||||||
|
||||||
## Examples | ||||||
|
||||||
- Try to run `fluence init --env kras --template ts frontend`. After that you can review `./frontend/src/gateway` and `./frontend/src/gateway` folders and check their code. | ||||||
- Check out more examples in the [example repo](https://github.com/fluencelabs/examples/tree/main/js-client-examples); You can find browser to browser interaction example there. | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# Extending Fluence functions (experimental) | ||
|
||
> This section is experimental as the API is not stable and probably will change. | ||
|
||
## Intro | ||
|
||
As you already know, JS client allows you to process incoming event and dispatch events to execute Aqua. | ||
Additionally, JS client provides API for creating not just JavaScript services but essentially with any programming language which support WASI compilation, e.g. rust, go. | ||
|
||
## Use cases | ||
|
||
Here are the reasons why you might want to write a Marine JS WASI service instead of writing a regular JavaScript service for JS client: | ||
- A service which works both on Nox peer and JS client peer, thus you eliminate the need to copy-paste the codelogic. | ||
- Heavy computations, CPU intensive tasks. Some languages cope with that better than high-level JavaScript. | ||
- Would prefer to write a service in Rust or other language with compilation to WASI (at this moment only Rust is officially supported) | ||
|
||
## What is Marine JS | ||
|
||
When JS client starts up, it starts with initialization of Marine JS runtime. | ||
The runtime hosts wasm services and even allows you to register your own wasm services. | ||
For example, AquaVM service (which process event data) resides in Marine JS. | ||
That's why Marine JS is a foundation of JS client. | ||
|
||
## Extending JS client with Marine services | ||
|
||
> Currently only [pure](https://fluence.dev/docs/build/glossary#pure-module) single-module services are supported. | ||
|
||
Using Marine services is pretty straight forward. The first thing to do is to load a compiled WASM file into your environment. | ||
|
||
### Loading module binary | ||
|
||
Here are the examples of how to load your wasm file in browser or Node.js | ||
|
||
**Node.js** | ||
|
||
```javascript | ||
import { readFile } from 'fs/promises'; | ||
|
||
const wasm = await readFile('path/to/wasm/file.wasm', 'base64'); | ||
``` | ||
|
||
**Browser** | ||
|
||
> Need to install additional external package in browser env - `js-base64` | ||
|
||
```javascript | ||
import { fromUint8Array } from 'js-base64'; | ||
|
||
const wasmBinary = await fetch('https://wasm.com/url/to/wasm').then(res => res.arrayBuffer()); | ||
const wasm = fromUint8Array(new Uint8Array(greetingWasm)); | ||
``` | ||
|
||
|
||
### Registering service in JS client | ||
|
||
JS client doesn't provide any specific interface for creating services in Marine JS. | ||
However, the client loads wasm content through its own special service called `Srv`. | ||
This is JS client's specific API that's why you need to add `Srv` definition in your Aqua project. | ||
|
||
Add the following aqua file in your project near the other aqua files. | ||
|
||
``` | ||
data ServiceCreationResult: | ||
success: bool | ||
service_id: ?string | ||
error: ?string | ||
|
||
data RemoveResult: | ||
success: bool | ||
error: ?string | ||
|
||
alias ListServiceResult: []string | ||
|
||
service Srv("single_module_srv"): | ||
-- Used to create a service on a certain node | ||
-- Arguments: | ||
-- bytes – a base64 string containing the .wasm module to add. | ||
-- Returns: service_id – the service ID of the created service. | ||
create(wasm_b64_content: string) -> ServiceCreationResult | ||
|
||
-- Used to remove a service from a certain node | ||
-- Arguments: | ||
-- service_id – ID of the service to remove | ||
remove(service_id: string) -> RemoveResult | ||
|
||
-- Returns a list of services ids running on a peer | ||
list() -> ListServiceResult | ||
``` | ||
Also, you need Aqua function which will call the service above. | ||
Here is an example of what that function could look like in a simple form. | ||
|
||
> In this example, wasm binary loaded as a string (see above) passed to Aqua function param. | ||
|
||
``` | ||
service GreetingService("service-id"): -- (1) | ||
greeting: string -> string | ||
|
||
func hello(name: string, wasm_content: string) -> string: | ||
created_service <- Srv.create(wasm_content) -- (2) | ||
Greeting created_service.service_id! -- (3) | ||
<- Greeting.greeting(name) -- (4) | ||
``` | ||
|
||
- (1) Service definition for the passed module | ||
- (2) Using JS client `Srv` service to register module as a service in Marine JS. | ||
- (3) Creating service variable. It will allow you to call methods from service definition | ||
- (4) Interacting with your single module service | ||
|
||
Then you need to pass `wasm` variable above as a second parameter in the function. | ||
|
||
> You can load and register as many WASM modules as you want. Remember to keep each of them in a separate service. | ||
|
||
There is a working marine service example in [examples repo](https://github.com/fluencelabs/examples/tree/main/js-client-examples/marine-service). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
terminology is outdated and needs to be updated through out. see https://github.com/fluencelabs/docs/tree/res-32-glossary.
also, for denver all we need is the concept piece not the tutorial. there is no need and no capacity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too broad comment
I would like to see more details from you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You also have kind of events-in-js doc in main branch already and it makes me confused.