mirror of
https://github.com/fluencelabs/registry.git
synced 2025-04-25 02:02:14 +00:00
fix(example): update example and fix bugs in Aqua code (#122)
This commit is contained in:
parent
fe030623f8
commit
6b51f9381b
@ -3,6 +3,7 @@ import "registry-service.aqua"
|
|||||||
import "constants.aqua"
|
import "constants.aqua"
|
||||||
|
|
||||||
alias ResourceId: string
|
alias ResourceId: string
|
||||||
|
alias Resource: Key
|
||||||
alias Error: string
|
alias Error: string
|
||||||
|
|
||||||
func wait(successful: *bool, len: i16, timeout: u16) -> bool:
|
func wait(successful: *bool, len: i16, timeout: u16) -> bool:
|
||||||
@ -25,7 +26,7 @@ func wait(successful: *bool, len: i16, timeout: u16) -> bool:
|
|||||||
|
|
||||||
-- Get peers closest to the resource_id's hash in Kademlia network
|
-- Get peers closest to the resource_id's hash in Kademlia network
|
||||||
-- These peers are expected to store list of providers for this key
|
-- These peers are expected to store list of providers for this key
|
||||||
func getNeighbours(resource_id: ResourceId) -> []PeerId:
|
func getNeighbors(resource_id: ResourceId) -> []PeerId:
|
||||||
k <- Op.string_to_b58(resource_id)
|
k <- Op.string_to_b58(resource_id)
|
||||||
nodes <- Kademlia.neighborhood(k, nil, nil)
|
nodes <- Kademlia.neighborhood(k, nil, nil)
|
||||||
<- nodes
|
<- nodes
|
||||||
@ -33,3 +34,34 @@ func getNeighbours(resource_id: ResourceId) -> []PeerId:
|
|||||||
func appendErrors(error1: *Error, error2: *Error):
|
func appendErrors(error1: *Error, error2: *Error):
|
||||||
for e <- error2:
|
for e <- error2:
|
||||||
error1 <<- e
|
error1 <<- e
|
||||||
|
|
||||||
|
func getResourceHelper(resource_id: ResourceId) -> ?Resource, *Error:
|
||||||
|
nodes <- getNeighbors(resource_id)
|
||||||
|
result: ?Resource
|
||||||
|
error: *Error
|
||||||
|
|
||||||
|
resources: *Key
|
||||||
|
successful: *bool
|
||||||
|
for n <- nodes par:
|
||||||
|
on n:
|
||||||
|
try:
|
||||||
|
get_result <- Registry.get_key_metadata(resource_id)
|
||||||
|
if get_result.success:
|
||||||
|
resources <<- get_result.key
|
||||||
|
successful <<- true
|
||||||
|
else:
|
||||||
|
e <- Op.concat_strings(get_result.error, " on ")
|
||||||
|
error <- Op.concat_strings(e, n)
|
||||||
|
|
||||||
|
success <- wait(successful, CONSISTENCY_LEVEL, DEFAULT_TIMEOUT)
|
||||||
|
if success == false:
|
||||||
|
error <<- "resource not found: timeout exceeded"
|
||||||
|
else:
|
||||||
|
merge_result <- Registry.merge_keys(resources)
|
||||||
|
|
||||||
|
if merge_result.success:
|
||||||
|
result <<- merge_result.key
|
||||||
|
else:
|
||||||
|
error <<- merge_result.error
|
||||||
|
|
||||||
|
<- result, error
|
||||||
|
@ -25,10 +25,19 @@ func getRecordMetadata(key_id: string, value: string, peer_id: string, relay_id:
|
|||||||
<- result, error
|
<- result, error
|
||||||
|
|
||||||
func getRecordSignature(metadata: RecordMetadata, timestamp_created: u64) -> SignResult:
|
func getRecordSignature(metadata: RecordMetadata, timestamp_created: u64) -> SignResult:
|
||||||
bytes <- Registry.get_record_bytes(metadata, timestamp_created)
|
signature: *SignResult
|
||||||
on metadata.peer_id via HOST_PEER_ID:
|
|
||||||
signature <- Sig.sign(bytes)
|
if metadata.peer_id != INIT_PEER_ID:
|
||||||
<- signature
|
on metadata.peer_id via HOST_PEER_ID:
|
||||||
|
bytes <- Registry.get_record_bytes(metadata, timestamp_created)
|
||||||
|
signature <- Sig.sign(bytes)
|
||||||
|
else:
|
||||||
|
on HOST_PEER_ID:
|
||||||
|
bytess <- Registry.get_record_bytes(metadata, timestamp_created)
|
||||||
|
on INIT_PEER_ID:
|
||||||
|
signature <- Sig.sign(bytess)
|
||||||
|
|
||||||
|
<- signature!
|
||||||
|
|
||||||
func getTombstoneSignature(key_id: string, peer_id: string, timestamp_issued: u64, solution: []u8) -> SignResult:
|
func getTombstoneSignature(key_id: string, peer_id: string, timestamp_issued: u64, solution: []u8) -> SignResult:
|
||||||
bytes <- Registry.get_tombstone_bytes(key_id, INIT_PEER_ID, peer_id, timestamp_issued, solution)
|
bytes <- Registry.get_tombstone_bytes(key_id, INIT_PEER_ID, peer_id, timestamp_issued, solution)
|
||||||
|
@ -10,41 +10,16 @@ alias ResourceId: string
|
|||||||
alias Resource: Key
|
alias Resource: Key
|
||||||
alias Error: string
|
alias Error: string
|
||||||
|
|
||||||
func getResourceId(label: string, peer_id: string) -> ResourceId:
|
|
||||||
resource_id <- Registry.get_key_id(label, peer_id)
|
|
||||||
<- resource_id
|
|
||||||
|
|
||||||
func getResource(resource_id: ResourceId) -> ?Resource, *Error:
|
func getResource(resource_id: ResourceId) -> ?Resource, *Error:
|
||||||
nodes <- getNeighbours(resource_id)
|
on HOST_PEER_ID:
|
||||||
result: ?Resource
|
result, error <- getResourceHelper(resource_id)
|
||||||
error: *Error
|
|
||||||
|
|
||||||
resources: *Key
|
|
||||||
successful: *bool
|
|
||||||
for n <- nodes par:
|
|
||||||
on n:
|
|
||||||
try:
|
|
||||||
get_result <- Registry.get_key_metadata(resource_id)
|
|
||||||
if get_result.success:
|
|
||||||
resources <<- get_result.key
|
|
||||||
successful <<- true
|
|
||||||
else:
|
|
||||||
e <- Op.concat_strings(get_result.error, " on ")
|
|
||||||
error <- Op.concat_strings(e, n)
|
|
||||||
|
|
||||||
success <- wait(successful, CONSISTENCY_LEVEL, DEFAULT_TIMEOUT)
|
|
||||||
if success == false:
|
|
||||||
error <<- "resource not found: timeout exceeded"
|
|
||||||
else:
|
|
||||||
merge_result <- Registry.merge_keys(resources)
|
|
||||||
|
|
||||||
if merge_result.success:
|
|
||||||
result <<- merge_result.key
|
|
||||||
else:
|
|
||||||
error <<- merge_result.error
|
|
||||||
|
|
||||||
<- result, error
|
<- result, error
|
||||||
|
|
||||||
|
func getResourceId(label: string, peer_id: string) -> ResourceId:
|
||||||
|
on HOST_PEER_ID:
|
||||||
|
resource_id <- Registry.get_key_id(label, peer_id)
|
||||||
|
<- resource_id
|
||||||
|
|
||||||
-- Create a resource: register it on the closest peers
|
-- Create a resource: register it on the closest peers
|
||||||
func createResource(label: string) -> ?ResourceId, *Error:
|
func createResource(label: string) -> ?ResourceId, *Error:
|
||||||
t <- Peer.timestamp_sec()
|
t <- Peer.timestamp_sec()
|
||||||
@ -57,8 +32,8 @@ func createResource(label: string) -> ?ResourceId, *Error:
|
|||||||
error <<- sig_result.error!
|
error <<- sig_result.error!
|
||||||
else:
|
else:
|
||||||
signature = sig_result.signature!
|
signature = sig_result.signature!
|
||||||
id <- getResourceId(label, INIT_PEER_ID)
|
id <- Registry.get_key_id(label, INIT_PEER_ID)
|
||||||
nodes <- getNeighbours(id)
|
nodes <- getNeighbors(id)
|
||||||
|
|
||||||
successful: *bool
|
successful: *bool
|
||||||
for n <- nodes par:
|
for n <- nodes par:
|
||||||
@ -101,7 +76,7 @@ func registerServiceRecord(resource_id: ResourceId, value: string, peer_id: Peer
|
|||||||
error <<- sig_result.error!
|
error <<- sig_result.error!
|
||||||
success <<- false
|
success <<- false
|
||||||
else:
|
else:
|
||||||
key, error_get <- getResource(resource_id)
|
key, error_get <- getResourceHelper(resource_id)
|
||||||
if key == nil:
|
if key == nil:
|
||||||
appendErrors(error, error_get)
|
appendErrors(error, error_get)
|
||||||
success <<- false
|
success <<- false
|
||||||
@ -117,7 +92,7 @@ func registerServiceRecord(resource_id: ResourceId, value: string, peer_id: Peer
|
|||||||
error <<- p_res.error
|
error <<- p_res.error
|
||||||
success <<- false
|
success <<- false
|
||||||
|
|
||||||
nodes <- getNeighbours(resource_id)
|
nodes <- getNeighbors(resource_id)
|
||||||
successful: *bool
|
successful: *bool
|
||||||
for n <- nodes par:
|
for n <- nodes par:
|
||||||
on n:
|
on n:
|
||||||
@ -168,7 +143,7 @@ func unregisterService(resource_id: ResourceId, peer_id: PeerId) -> bool, *Error
|
|||||||
error <<- res.error
|
error <<- res.error
|
||||||
success <<- false
|
success <<- false
|
||||||
|
|
||||||
nodes <- getNeighbours(resource_id)
|
nodes <- getNeighbors(resource_id)
|
||||||
successful: *bool
|
successful: *bool
|
||||||
for n <- nodes par:
|
for n <- nodes par:
|
||||||
on n:
|
on n:
|
||||||
@ -192,7 +167,7 @@ func unregisterService(resource_id: ResourceId, peer_id: PeerId) -> bool, *Error
|
|||||||
|
|
||||||
func resolveResource(resource_id: ResourceId, ack: i16) -> []Record, *Error:
|
func resolveResource(resource_id: ResourceId, ack: i16) -> []Record, *Error:
|
||||||
on HOST_PEER_ID:
|
on HOST_PEER_ID:
|
||||||
nodes <- getNeighbours(resource_id)
|
nodes <- getNeighbors(resource_id)
|
||||||
res: *[]Record
|
res: *[]Record
|
||||||
error: *Error
|
error: *Error
|
||||||
successful: *bool
|
successful: *bool
|
||||||
|
@ -2,19 +2,25 @@
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The example shows one of the important Registry use-cases — services advertisement and discovery. So it is about advertisement by providers, discovery and usage by clients with the same Aqua code transparently without any knowledge about particular peer and service ids.
|
The example shows one of the important Registry use-cases — services advertisement and discovery. So it is about discovery and usage by clients with the same Aqua code transparently without any knowledge about particular peer and service ids.
|
||||||
|
|
||||||
In the beginning, we will deploy a Rust echo service and call it with the Fluence CLI.
|
In the beginning, we will deploy a Rust echo service and call it with the Fluence CLI.
|
||||||
Then we will start a JS/TS client with echo service and run it.
|
Then we will start a JS/TS client with echo service and run it.
|
||||||
|
|
||||||
Finally, we will use Registry to call different types of services with exactly one piece of code.
|
Secondly, we will use Registry to call registered services with exactly one piece of code without peer and service identifiers.
|
||||||
|
And finally, we will show how to remove service records.
|
||||||
|
|
||||||
## Requirements
|
## Note
|
||||||
|
If you face any dependencies issue, you can try to use `fluence dependency` to install any version of `aqua`, `marine` and `mrepl` available in npm and cargo registries:
|
||||||
|
|
||||||
```markdown
|
```bash
|
||||||
node: >= 16
|
$ fluence dependency
|
||||||
rust: rustc 1.63.0-nightly
|
? Select dependency (Use arrow keys)
|
||||||
@fluencelabs/cli: 0.2.7
|
NPM dependencies:
|
||||||
|
❯ aqua
|
||||||
|
Cargo dependencies:
|
||||||
|
marine
|
||||||
|
mrepl
|
||||||
```
|
```
|
||||||
|
|
||||||
# Set up environment
|
# Set up environment
|
||||||
@ -22,7 +28,7 @@ rust: rustc 1.63.0-nightly
|
|||||||
1. Install `fluence` cli:
|
1. Install `fluence` cli:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm i -g @fluencelabs/cli@0.2.7
|
npm i -g @fluencelabs/cli
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Initialize Fluence project:
|
2. Initialize Fluence project:
|
||||||
@ -35,15 +41,21 @@ rust: rustc 1.63.0-nightly
|
|||||||
Successfully initialized Fluence project template at <your-path-to-registry-repo>/example
|
Successfully initialized Fluence project template at <your-path-to-registry-repo>/example
|
||||||
```
|
```
|
||||||
|
|
||||||
3. You can use [VSCode with Aqua extension](https://marketplace.visualstudio.com/items?itemName=FluenceLabs.aqua) for syntax highlighting and better developer experience.
|
3. Install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm i
|
||||||
|
```
|
||||||
|
|
||||||
|
4. You can use [VSCode with Aqua extension](https://marketplace.visualstudio.com/items?itemName=FluenceLabs.aqua) for syntax highlighting and better developer experience.
|
||||||
|
|
||||||
## Add echo service in Rust
|
## Add echo service in Rust
|
||||||
|
|
||||||
0. If you have **Apple Silicon** you should install cargo manually, or you can ignore this step otherwise:
|
0. If you have **Apple Silicon** you should install `marine` manually, or you can ignore this step otherwise:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# for m1:
|
# for m1:
|
||||||
cargo install marine --version '0.12.1' --root ~/.fluence/cargo
|
cargo install marine --root ~/.fluence/cargo
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Add echo service:
|
1. Add echo service:
|
||||||
@ -69,11 +81,11 @@ rust: rustc 1.63.0-nightly
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Test echo service locally with REPL
|
### Test echo service locally with REPL
|
||||||
0. If you have **Apple Silicon** you should install mrepl manually, or you can ignore this step otherwise:
|
0. If you have **Apple Silicon** you should install `mrepl` manually, or you can ignore this step otherwise:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# for m1:
|
# for m1:
|
||||||
cargo install mrepl --version '0.18.0' --root ~/.fluence/cargo
|
cargo install mrepl --root ~/.fluence/cargo
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Run the following command to start REPL:
|
1. Run the following command to start REPL:
|
||||||
@ -184,20 +196,19 @@ You can always test your services before deployment with REPL. Check out [docume
|
|||||||
|
|
||||||
Result:
|
Result:
|
||||||
|
|
||||||
"12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS: hi"
|
[
|
||||||
|
[
|
||||||
|
"12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi: hi"
|
||||||
|
]
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
We've successfully built and deployed a service written in Rust, and called it from our Aqua code using the Fluence CLI.
|
We've successfully built and deployed a service written in Rust, and called it from our Aqua code using the Fluence CLI.
|
||||||
|
|
||||||
## Run echo service in JS/TS:
|
## Run echo service in JS/TS:
|
||||||
|
|
||||||
1. Install dependencies:
|
|
||||||
|
|
||||||
```bash
|
1. Check out [src/aqua/export.aqua](src/aqua/export.aqua) with an export of EchoService API to JS/TS:
|
||||||
npm i
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Check out [src/aqua/export.aqua](src/aqua/export.aqua) with an export of EchoService API to JS/TS:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
module Export
|
module Export
|
||||||
@ -205,7 +216,7 @@ We've successfully built and deployed a service written in Rust, and called it f
|
|||||||
export EchoService
|
export EchoService
|
||||||
```
|
```
|
||||||
|
|
||||||
3. The following [code](src/echo.ts#L23) registers a local EchoService:
|
2. The following [code](src/echo.ts#L23) registers a local EchoService:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// register local service with service id "echo"
|
// register local service with service id "echo"
|
||||||
@ -215,7 +226,7 @@ We've successfully built and deployed a service written in Rust, and called it f
|
|||||||
}});
|
}});
|
||||||
```
|
```
|
||||||
|
|
||||||
4. The following [code](src/aqua/main.aqua) is calling our local JS/TS peer with `EchoService`:
|
3. The following [code](src/aqua/main.aqua) is calling our local JS/TS peer with `EchoService`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
func echoJS(peer: string, relay: string, serviceId: string, msg: string) -> string:
|
func echoJS(peer: string, relay: string, serviceId: string, msg: string) -> string:
|
||||||
@ -225,7 +236,7 @@ We've successfully built and deployed a service written in Rust, and called it f
|
|||||||
<- res
|
<- res
|
||||||
```
|
```
|
||||||
<a id="running-service"></a>
|
<a id="running-service"></a>
|
||||||
5. Start the client with our service: `npm run start`
|
4. Start the client with our service: `npm run start`
|
||||||
```bash
|
```bash
|
||||||
...
|
...
|
||||||
> example@1.0.0 start
|
> example@1.0.0 start
|
||||||
@ -236,7 +247,7 @@ We've successfully built and deployed a service written in Rust, and called it f
|
|||||||
fluence run -f 'echoJS("12D3KooWCmnhnGvKTqEXpVLzdrYu3TkQ3HcLyArGJpLPooJQ69dN", "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi", "echo", "msg")'
|
fluence run -f 'echoJS("12D3KooWCmnhnGvKTqEXpVLzdrYu3TkQ3HcLyArGJpLPooJQ69dN", "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi", "echo", "msg")'
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Open a new terminal in the same registry example directory, and execute the following command to check echo service:
|
5. Open a new terminal in the same registry example directory, and execute the following command to check echo service:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ fluence run -f 'echoJS("12D3KooWCmnhnGvKTqEXpVLzdrYu3TkQ3HcLyArGJpLPooJQ69dN", "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi", "echo", "msg")'
|
$ fluence run -f 'echoJS("12D3KooWCmnhnGvKTqEXpVLzdrYu3TkQ3HcLyArGJpLPooJQ69dN", "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi", "echo", "msg")'
|
||||||
@ -255,7 +266,7 @@ We've successfully started JS/TS peer with an EchoService and tested it with Flu
|
|||||||
|
|
||||||
As service providers we would like all our echo services to be discoverable without specifying particular peer and service ids, in order to achieve that we should use Registry to **advertise** our services.
|
As service providers we would like all our echo services to be discoverable without specifying particular peer and service ids, in order to achieve that we should use Registry to **advertise** our services.
|
||||||
|
|
||||||
Firstly, we need to create a **resource.** A resource represents a group of service providers and has a corresponding resource id for its discovery. Secondly, we need to register the service providers on this resource id. So the echo services can be discovered and resolved by the resource id only.
|
Firstly, we need to create a **resource.** A resource represents a group of services and has a corresponding resource id for its discovery. Secondly, we need to register the service records on this resource id. So the echo services can be discovered and resolved by the resource id only.
|
||||||
|
|
||||||
1. The following [code](src/aqua/main.aqua#L24) registers resource with label `echo`:
|
1. The following [code](src/aqua/main.aqua#L24) registers resource with label `echo`:
|
||||||
|
|
||||||
@ -283,36 +294,37 @@ Firstly, we need to create a **resource.** A resource represents a group of serv
|
|||||||
Result:
|
Result:
|
||||||
|
|
||||||
[
|
[
|
||||||
"echo12D3KooWRgEgxP4qAyUR5jerwKE1rwTLZoAhJ3YwAhpeSMC5pi77"
|
"5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB"
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
So the resource id is `echo12D3KooWRgEgxP4qAyUR5jerwKE1rwTLZoAhJ3YwAhpeSMC5pi77`. Please note that the resource id might be different in your case.
|
So the resource id is `5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB`. Please note that the resource id might be different in your case.
|
||||||
|
|
||||||
Using the resource id we can access any registered provider of the resource. There can be more registered echo services on different peers that we can use transparently.
|
Using the resource id we can access any registered service. There can be more registered echo services on different peers that we can use transparently.
|
||||||
|
|
||||||
3. This [code](src/aqua/main.aqua#L28) registers deployed service by given `resource_id`:
|
3. This [code](src/aqua/main.aqua#L28) registers deployed service by given `resource_id`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
func registerService(resource_id: string) -> bool:
|
func registerService(resource_id: string) -> *bool:
|
||||||
|
results: *bool
|
||||||
services <- App.services()
|
services <- App.services()
|
||||||
echoService = services.echoService.default[0]
|
for srv <- services.echoService.default:
|
||||||
success, error <- registerNodeProvider(echoService.peerId, resource_id, "", ?[echoService.serviceId])
|
results <- registerServiceRecord(resource_id, "" ,srv.peerId, ?[srv.serviceId])
|
||||||
<- success
|
<- results
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Register service for resource_id from [the step 2](#resource-id):
|
4. Register service for resource_id from [the step 2](#resource-id):
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fluence run -f 'registerService("echo12D3KooWRgEgxP4qAyUR5jerwKE1rwTLZoAhJ3YwAhpeSMC5pi77")'
|
fluence run -f 'registerService("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB")'
|
||||||
```
|
```
|
||||||
|
|
||||||
output:
|
output:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ fluence run -f 'registerService("echo12D3KooWRgEgxP4qAyUR5jerwKE1rwTLZoAhJ3YwAhpeSMC5pi77")'
|
$ fluence run -f 'registerService("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB")'
|
||||||
Running:
|
Running:
|
||||||
function: registerService("echo12D3KooWCWsJLrG6evQKPEsDmKNbaW8NGj5JhVZfHumSvyx1Zw4c")
|
function: registerService("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB")
|
||||||
relay: /dns4/kras-05.fluence.dev/tcp/19001/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS
|
relay: /dns4/kras-05.fluence.dev/tcp/19001/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS
|
||||||
... done
|
... done
|
||||||
|
|
||||||
@ -328,19 +340,19 @@ Firstly, we need to create a **resource.** A resource represents a group of serv
|
|||||||
5. Next, we need to register JS service. For that we have Aqua imports and exports in [src/aqua/export.aqua](src/aqua/export.aqua):
|
5. Next, we need to register JS service. For that we have Aqua imports and exports in [src/aqua/export.aqua](src/aqua/export.aqua):
|
||||||
|
|
||||||
```
|
```
|
||||||
import registerProvider from "@fluencelabs/registry/resources-api.aqua"
|
import registerServiceRecord from "@fluencelabs/registry/resources-api.aqua"
|
||||||
export registerProvider
|
export registerServiceRecord
|
||||||
```
|
```
|
||||||
|
|
||||||
6. In [src/echo.ts](src/echo.ts#L32) we should pass resource id as cmd argument:
|
6. In [src/echo.ts](src/echo.ts#L32) we should pass resource id as cmd argument:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
let [success, error] = await registerProvider(process.argv[2], "echo", serviceId);
|
let [success, error] = await registerServiceRecord(process.argv[2], "echo", peerId, serviceId);
|
||||||
console.log("registration result: ", success);
|
console.log("registration result: ", success);
|
||||||
```
|
```
|
||||||
|
|
||||||
7. So, stop the previous JS client from [the step 5](#running-service) and run
|
7. So, stop the previous JS client from [the step 5](#running-service) and run
|
||||||
`npm run start echo12D3KooWRgEgxP4qAyUR5jerwKE1rwTLZoAhJ3YwAhpeSMC5pi77` (Note: resource_id is from [the step 2](#resource-id))
|
`npm run start 5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB` (Note: resource_id is from [the step 2](#resource-id))
|
||||||
output:
|
output:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
@ -358,12 +370,12 @@ We've successfully registered both services, JS/TS and Rust, in Registry and now
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
func echoAll(resource_id: string, msg: string) -> *string:
|
func echoAll(resource_id: string, msg: string) -> *string:
|
||||||
-- 2 is the min number of providers we want to find
|
-- 2 is the min number of peers we want to ask
|
||||||
providers <- resolveProviders(resource_id, 2)
|
records <- resolveResource(resource_id, 2)
|
||||||
results: *string
|
results: *string
|
||||||
for p <- providers:
|
for r <- records:
|
||||||
on p.peer_id via p.relay_id:
|
on r.metadata.peer_id via r.metadata.relay_id:
|
||||||
EchoService p.service_id!
|
EchoService r.metadata.service_id!
|
||||||
results <- EchoService.echo(msg)
|
results <- EchoService.echo(msg)
|
||||||
<- results
|
<- results
|
||||||
```
|
```
|
||||||
@ -371,14 +383,14 @@ We've successfully registered both services, JS/TS and Rust, in Registry and now
|
|||||||
2. Let’s run all registered echo services with only resource id:
|
2. Let’s run all registered echo services with only resource id:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
fluence run -f 'echoAll("echo12D3KooWRgEgxP4qAyUR5jerwKE1rwTLZoAhJ3YwAhpeSMC5pi77", "hi")'
|
fluence run -f 'echoAll("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB", "hi")'
|
||||||
```
|
```
|
||||||
|
|
||||||
output:
|
output:
|
||||||
```
|
```
|
||||||
$ fluence run -f 'echoAll("echo12D3KooWRgEgxP4qAyUR5jerwKE1rwTLZoAhJ3YwAhpeSMC5pi77", "hi")'
|
$ fluence run -f 'echoAll("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB", "hi")'
|
||||||
Running:
|
Running:
|
||||||
function: echoAll("echo12D3KooWRgEgxP4qAyUR5jerwKE1rwTLZoAhJ3YwAhpeSMC5pi77", "hi")
|
function: echoAll("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB", "hi")
|
||||||
relay: /dns4/kras-06.fluence.dev/tcp/19001/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr
|
relay: /dns4/kras-06.fluence.dev/tcp/19001/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr
|
||||||
... done
|
... done
|
||||||
|
|
||||||
@ -392,3 +404,62 @@ We've successfully registered both services, JS/TS and Rust, in Registry and now
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Remove service record
|
||||||
|
|
||||||
|
If we want to remove a service record from resource, we should use `unregisterService` method from Resources API:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
func unregisterEchoService(resource_id: string) -> *bool:
|
||||||
|
results: *bool
|
||||||
|
services <- App.services()
|
||||||
|
for srv <- services.echoService.default:
|
||||||
|
results <- unregisterService(resource_id, srv.peerId)
|
||||||
|
<- results
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Let's unregister our deployed EchoService:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fluence run -f 'unregisterEchoService("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB")'
|
||||||
|
```
|
||||||
|
output:
|
||||||
|
```
|
||||||
|
$ fluence run -f 'unregisterEchoService("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB")'
|
||||||
|
Running:
|
||||||
|
function: unregisterEchoService("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB")
|
||||||
|
relay: /dns4/kras-05.fluence.dev/tcp/19001/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS
|
||||||
|
... done
|
||||||
|
|
||||||
|
Result:
|
||||||
|
|
||||||
|
[
|
||||||
|
[
|
||||||
|
true
|
||||||
|
]
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Let’s run again `echoAll` method:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fluence run -f 'echoAll("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB", "hi")'
|
||||||
|
```
|
||||||
|
|
||||||
|
output:
|
||||||
|
```
|
||||||
|
$ fluence run -f 'echoAll("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB", "hi")'
|
||||||
|
Running:
|
||||||
|
function: echoAll("5pYpWB3ozi6fi1EjNs9X5kE156aA6iLECxTuVdJgUaLB", "hi")
|
||||||
|
relay: /dns4/kras-06.fluence.dev/tcp/19001/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr
|
||||||
|
... done
|
||||||
|
|
||||||
|
Result:
|
||||||
|
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"12D3KooWCmnhnGvKTqEXpVLzdrYu3TkQ3HcLyArGJpLPooJQ69dN: hi"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
So now we know how to add and remove service records for Resource and use it for advertising and discovering services in runtime.
|
||||||
|
@ -3,7 +3,7 @@ module Main
|
|||||||
import App from "deployed.app.aqua"
|
import App from "deployed.app.aqua"
|
||||||
import EchoService from "services/echoService.aqua"
|
import EchoService from "services/echoService.aqua"
|
||||||
import "@fluencelabs/registry/resources-api.aqua"
|
import "@fluencelabs/registry/resources-api.aqua"
|
||||||
export App, echo, echoJS, registerResource, registerServiceRecord, echoAll
|
export App, echo, echoJS, registerResource, registerService, echoAll, unregisterEchoService
|
||||||
|
|
||||||
func echo(msg: string) -> *string:
|
func echo(msg: string) -> *string:
|
||||||
services <- App.services()
|
services <- App.services()
|
||||||
@ -29,15 +29,22 @@ func registerService(resource_id: string) -> *bool:
|
|||||||
results: *bool
|
results: *bool
|
||||||
services <- App.services()
|
services <- App.services()
|
||||||
for srv <- services.echoService.default:
|
for srv <- services.echoService.default:
|
||||||
results, error <- registerServiceRecord(srv.peerId, resource_id, "", ?[srv.serviceId])
|
results <- registerServiceRecord(resource_id, "" ,srv.peerId, ?[srv.serviceId])
|
||||||
|
<- results
|
||||||
|
|
||||||
|
func unregisterEchoService(resource_id: string) -> *bool:
|
||||||
|
results: *bool
|
||||||
|
services <- App.services()
|
||||||
|
for srv <- services.echoService.default:
|
||||||
|
results <- unregisterService(resource_id, srv.peerId)
|
||||||
<- results
|
<- results
|
||||||
|
|
||||||
func echoAll(resource_id: string, msg: string) -> *string:
|
func echoAll(resource_id: string, msg: string) -> *string:
|
||||||
-- 2 is the min number of providers we want to find
|
-- 2 is the min number of peers we want to ask
|
||||||
records <- resolveResource(resource_id, 2)
|
records <- resolveResource(resource_id, 2)
|
||||||
results: *string
|
results: *string
|
||||||
for r <- records:
|
for r <- records:
|
||||||
on r.peer_id via r.relay_id:
|
on r.metadata.peer_id via r.metadata.relay_id:
|
||||||
EchoService r.service_id!
|
EchoService r.metadata.service_id!
|
||||||
results <- EchoService.echo(msg)
|
results <- EchoService.echo(msg)
|
||||||
<- results
|
<- results
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Fluence, KeyPair } from "@fluencelabs/fluence"
|
import { Fluence, KeyPair } from "@fluencelabs/fluence"
|
||||||
import { stage } from "@fluencelabs/fluence-network-environment"
|
import { krasnodar } from "@fluencelabs/fluence-network-environment"
|
||||||
import { registerEchoService } from "./generated/export"
|
import { registerEchoService } from "./generated/export"
|
||||||
import { registerServiceRecord } from "./generated/export"
|
import { registerServiceRecord } from "./generated/export"
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ const sk = "Iz3HUmNIB78lkNNVmMkDKrju0nCivtkJNyObrFAr774=";
|
|||||||
async function main() {
|
async function main() {
|
||||||
const keypair = await KeyPair.fromEd25519SK(Buffer.from(sk, 'base64'));
|
const keypair = await KeyPair.fromEd25519SK(Buffer.from(sk, 'base64'));
|
||||||
// connect to the Fluence network
|
// connect to the Fluence network
|
||||||
await Fluence.start({ connectTo: stage[5], KeyPair: keypair });
|
await Fluence.start({ connectTo: krasnodar[5], KeyPair: keypair });
|
||||||
console.log(
|
console.log(
|
||||||
"📗 created a fluence peer %s with relay %s",
|
"📗 created a fluence peer %s with relay %s",
|
||||||
Fluence.getStatus().peerId,
|
Fluence.getStatus().peerId,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user