Skip to content
This repository was archived by the owner on Feb 26, 2026. It is now read-only.

Commit 7dcf564

Browse files
authored
NOISSUE - Document Host Runtime (#12)
* docs: host runtime * docs: proxy documentation * docs(api): update * docs(registry): how to push to registry Signed-off-by: Rodney Osodo <socials@rodneyosodo.com> * style: fix linter --------- Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
1 parent e43ae1f commit 7dcf564

File tree

4 files changed

+360
-48
lines changed

4 files changed

+360
-48
lines changed

docs/api/postman_collection.json

Lines changed: 182 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"info": {
3-
"_postman_id": "3ce70d97-6e67-4bc9-810f-1ea801bc55f9",
3+
"_postman_id": "ff50e552-db77-444a-8119-176646f48f22",
44
"name": "Propeller",
55
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
66
"_exporter_id": "5838754",
7-
"_collection_link": "https://ox6flab.postman.co/workspace/Magistrala~acba89f8-0255-435e-9547-59e542474e21/collection/5838754-3ce70d97-6e67-4bc9-810f-1ea801bc55f9?action=share&source=collection_link&creator=5838754"
7+
"_collection_link": "https://ox6flab.postman.co/workspace/Magistrala~acba89f8-0255-435e-9547-59e542474e21/collection/5838754-ff50e552-db77-444a-8119-176646f48f22?action=share&source=collection_link&creator=5838754"
88
},
99
"item": [
1010
{
@@ -19,13 +19,13 @@
1919
"method": "GET",
2020
"header": [],
2121
"url": {
22-
"raw": "{{MANAGER_BASE_URL}}/proplets/{{PROPELLER_ID}}",
22+
"raw": "{{MANAGER_BASE_URL}}/proplets/{{WORKER_ID}}",
2323
"host": [
2424
"{{MANAGER_BASE_URL}}"
2525
],
2626
"path": [
2727
"proplets",
28-
"{{PROPELLER_ID}}"
28+
"{{WORKER_ID}}"
2929
]
3030
}
3131
},
@@ -99,7 +99,7 @@
9999
"header": [],
100100
"body": {
101101
"mode": "raw",
102-
"raw": "{\n \"name\": \"main\",\n \"image_url\": \"docker.io/mrstevenyaga/add.wasm\",\n \"file\": \"AGFzbQEAAAABBwFgAn9/AX8DAgEABwgBBG1haW4AAAoJAQcAIAAgAWoL\",\n \"inputs\": [\n 10,\n 20\n ]\n}",
102+
"raw": "{\n \"name\": \"main\",\n // \"image_url\": \"docker.io/mrstevenyaga/add.wasm\",\n \"file\": \"AGFzbQEAAAABBwFgAn9/AX8DAgEABwgBBG1haW4AAAoJAQcAIAAgAWoL\",\n \"inputs\": [\n 10,\n 20\n ]\n}",
103103
"options": {
104104
"raw": {
105105
"language": "json"
@@ -180,7 +180,177 @@
180180
]
181181
},
182182
{
183-
"name": "Create Task",
183+
"name": "Host Runtime",
184+
"item": [
185+
{
186+
"name": "Create Task",
187+
"event": [
188+
{
189+
"listen": "test",
190+
"script": {
191+
"exec": [
192+
"function constructVisualizerPayload() {",
193+
" var res = pm.response.json();",
194+
" var id = res.id;",
195+
" return id;",
196+
"}",
197+
"",
198+
"pm.collectionVariables.set('TASK_ID', constructVisualizerPayload());",
199+
""
200+
],
201+
"type": "text/javascript",
202+
"packages": {}
203+
}
204+
},
205+
{
206+
"listen": "prerequest",
207+
"script": {
208+
"exec": [
209+
""
210+
],
211+
"type": "text/javascript",
212+
"packages": {}
213+
}
214+
}
215+
],
216+
"request": {
217+
"method": "POST",
218+
"header": [],
219+
"body": {
220+
"mode": "raw",
221+
"raw": "{\n \"name\": \"add\",\n \"cli_args\": [\n \"--invoke\",\n \"add\"\n ],\n \"inputs\": [\n 10,\n 20\n ]\n}",
222+
"options": {
223+
"raw": {
224+
"language": "json"
225+
}
226+
}
227+
},
228+
"url": {
229+
"raw": "{{MANAGER_BASE_URL}}/tasks",
230+
"host": [
231+
"{{MANAGER_BASE_URL}}"
232+
],
233+
"path": [
234+
"tasks"
235+
]
236+
}
237+
},
238+
"response": []
239+
},
240+
{
241+
"name": "Get Task",
242+
"request": {
243+
"method": "GET",
244+
"header": [],
245+
"url": {
246+
"raw": "{{MANAGER_BASE_URL}}/tasks/{{TASK_ID}}",
247+
"host": [
248+
"{{MANAGER_BASE_URL}}"
249+
],
250+
"path": [
251+
"tasks",
252+
"{{TASK_ID}}"
253+
]
254+
}
255+
},
256+
"response": []
257+
},
258+
{
259+
"name": "Upload Wasm File",
260+
"event": [
261+
{
262+
"listen": "test",
263+
"script": {
264+
"exec": [
265+
""
266+
],
267+
"type": "text/javascript",
268+
"packages": {}
269+
}
270+
},
271+
{
272+
"listen": "prerequest",
273+
"script": {
274+
"exec": [
275+
""
276+
],
277+
"type": "text/javascript",
278+
"packages": {}
279+
}
280+
}
281+
],
282+
"request": {
283+
"method": "PUT",
284+
"header": [],
285+
"body": {
286+
"mode": "formdata",
287+
"formdata": [
288+
{
289+
"key": "file",
290+
"type": "file",
291+
"src": "/home/rodneyosodo/code/absmach/propeller/build/addition.wasm"
292+
}
293+
]
294+
},
295+
"url": {
296+
"raw": "{{MANAGER_BASE_URL}}/tasks/{{TASK_ID}}/upload",
297+
"host": [
298+
"{{MANAGER_BASE_URL}}"
299+
],
300+
"path": [
301+
"tasks",
302+
"{{TASK_ID}}",
303+
"upload"
304+
]
305+
}
306+
},
307+
"response": []
308+
},
309+
{
310+
"name": "Start Task",
311+
"event": [
312+
{
313+
"listen": "test",
314+
"script": {
315+
"exec": [
316+
""
317+
],
318+
"type": "text/javascript",
319+
"packages": {}
320+
}
321+
},
322+
{
323+
"listen": "prerequest",
324+
"script": {
325+
"exec": [
326+
""
327+
],
328+
"type": "text/javascript",
329+
"packages": {}
330+
}
331+
}
332+
],
333+
"request": {
334+
"method": "POST",
335+
"header": [],
336+
"url": {
337+
"raw": "{{MANAGER_BASE_URL}}/tasks/{{TASK_ID}}/start",
338+
"host": [
339+
"{{MANAGER_BASE_URL}}"
340+
],
341+
"path": [
342+
"tasks",
343+
"{{TASK_ID}}",
344+
"start"
345+
]
346+
}
347+
},
348+
"response": []
349+
}
350+
]
351+
},
352+
{
353+
"name": "Create Task With Image",
184354
"event": [
185355
{
186356
"listen": "test",
@@ -198,24 +368,14 @@
198368
"type": "text/javascript",
199369
"packages": {}
200370
}
201-
},
202-
{
203-
"listen": "prerequest",
204-
"script": {
205-
"exec": [
206-
""
207-
],
208-
"type": "text/javascript",
209-
"packages": {}
210-
}
211371
}
212372
],
213373
"request": {
214374
"method": "POST",
215375
"header": [],
216376
"body": {
217377
"mode": "raw",
218-
"raw": "{\n \"name\": \"add\",\n \"inputs\": [\n 10,\n 20\n ]\n}",
378+
"raw": "{\n \"name\": \"add\",\n \"inputs\": [\n 10,\n 20\n ],\n \"image_url\": \"localhost:5000/addition.wasm\"\n}",
219379
"options": {
220380
"raw": {
221381
"language": "json"
@@ -235,7 +395,7 @@
235395
"response": []
236396
},
237397
{
238-
"name": "Create Task With OCI Image",
398+
"name": "Create Task",
239399
"event": [
240400
{
241401
"listen": "test",
@@ -270,7 +430,7 @@
270430
"header": [],
271431
"body": {
272432
"mode": "raw",
273-
"raw": "{\n \"name\": \"add\",\n \"image_url\": \"docker.io/mrstevenyaga/add.wasm\",\n \"inputs\": [\n 10,\n 20\n ]\n}",
433+
"raw": "{\n \"name\": \"add\",\n \"inputs\": [\n 10,\n 20\n ]\n}",
274434
"options": {
275435
"raw": {
276436
"language": "json"
@@ -336,7 +496,7 @@
336496
"header": [],
337497
"body": {
338498
"mode": "raw",
339-
"raw": "{\n \"name\": \"main\",\n \"file\": \"AGFzbQEAAAABBwFgAn9/AX8DAgEABwgBBG1haW4AAAoJAQcAIAAgAWoL\",\n \"inputs\": [\n 10,\n 20\n ]\n}",
499+
"raw": "{\n \"name\": \"add\",\n \"inputs\": [\n 10,\n 20\n ]\n}",
340500
"options": {
341501
"raw": {
342502
"language": "json"
@@ -596,12 +756,12 @@
596756
"type": "string"
597757
},
598758
{
599-
"key": "PROPELLER_ID",
759+
"key": "WORKER_ID",
600760
"value": ""
601761
},
602762
{
603763
"key": "TASK_ID",
604764
"value": ""
605765
}
606766
]
607-
}
767+
}

docs/manager.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ The Manager service includes endpoints for health checks and metrics collection:
6464

6565
- A client sends a `POST` request to the `/tasks/{taskID}/start` endpoint to start a task.
6666
- The service retrieves the task from the tasks storage and selects an appropriate proplet using the scheduler.
67+
- The task can also specify which proplet to use.
6768
- The service publishes a start message to the MQTT topic for the selected proplet.
6869
- The proplet executes the task and publishes the results to the MQTT topic.
6970
- The service processes the results and updates the task state in the tasks storage.

docs/proplet.md

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,70 @@
11
# Proplet
22

3+
The `proplet` is a worker that executes WebAssembly functions. It can be configured to use either the embedded `wazero` runtime or an external WebAssembly runtime on the host system.
4+
5+
## Configuration
6+
7+
The `proplet` is configured using environment variables.
8+
9+
| Environment Variable | Description | Default |
10+
| ------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------- |
11+
| `PROPLET_LOG_LEVEL` | Log level (e.g., `debug`, `info`, `warn`, `error`) | `info` |
12+
| `PROPLET_INSTANCE_ID` | A unique ID for this proplet instance. | A new UUID |
13+
| `PROPLET_MQTT_ADDRESS` | The address of the MQTT broker. | `tcp://localhost:1883` |
14+
| `PROPLET_MQTT_TIMEOUT` | The timeout for MQTT operations. | `30s` |
15+
| `PROPLET_MQTT_QOS` | The Quality of Service level for MQTT messages. | `2` |
16+
| `PROPLET_LIVELINESS_INTERVAL` | The interval at which the proplet sends liveliness messages. | `10s` |
17+
| `PROPLET_DOMAIN_ID` | The domain ID for this proplet. | |
18+
| `PROPLET_CHANNEL_ID` | The channel ID for this proplet. | |
19+
| `PROPLET_CLIENT_ID` | The client ID for MQTT authentication. | |
20+
| `PROPLET_CLIENT_KEY` | The client key for MQTT authentication. | |
21+
| `PROPLET_EXTERNAL_WASM_RUNTIME` | The path to an external WebAssembly runtime. If not set, the embedded `wazero` runtime will be used. | `""` (empty string) |
22+
23+
## Usage
24+
25+
### Using the Embedded `wazero` Runtime
26+
27+
By default, `proplet` uses the embedded `wazero` runtime. To run it, simply set the required environment variables and start the application:
28+
29+
```bash
30+
export PROPLET_DOMAIN_ID="your_domain_id"
31+
export PROPLET_CHANNEL_ID="your_channel_id"
32+
export PROPLET_CLIENT_ID="your_client_id"
33+
export PROPLET_CLIENT_KEY="your_client_key"
34+
propeller-proplet
35+
```
36+
37+
### Using a Host WebAssembly Runtime
38+
39+
To use an external WebAssembly runtime (e.g., `wasmtime`, `wasmer`), set the `PROPLET_EXTERNAL_WASM_RUNTIME` environment variable to the path of the runtime executable.
40+
41+
For example, to use `wasmtime`:
42+
43+
```bash
44+
export PROPLET_DOMAIN_ID="your_domain_id"
45+
export PROPLET_CHANNEL_ID="your_channel_id"
46+
export PROPLET_CLIENT_ID="your_client_id"
47+
export PROPLET_CLIENT_KEY="your_client_key"
48+
export PROPLET_EXTERNAL_WASM_RUNTIME="/usr/bin/wasmtime"
49+
PROPLET_EXTERNAL_WASM_RUNTIME=wasmtime propeller-proplet
50+
```
51+
52+
You will also need to provide cli arguments to the task so that the runtime can be started. For example, to run the `addition` example with `wasmtime`:
53+
54+
```bash
55+
wasmtime --invoke add /home/rodneyosodo/code/absmach/propeller/db3d44e8-6e27-464a-aaeb-e643ec298dff.wasm 10 20
56+
```
57+
58+
Hence the cli aguments are `--invoke` and `add` and the path to the wasm file. The task will then be created as follows:
59+
60+
```json
61+
{
62+
"name": "add",
63+
"cli_args": ["--invoke", "add"],
64+
"inputs": [10, 20]
65+
}
66+
```
67+
368
## **Proplet Command Handling**
469

570
### **Start Command Flow**
@@ -43,8 +108,6 @@ The `StartApp` function in `runtime.go` handles the instantiation and execution
43108

44109
A success message is logged if the application starts successfully, while detailed errors are logged if any step in the process (e.g., chunk assembly, instantiation, or execution) fails.
45110

46-
---
47-
48111
### **Stop Command Flow**
49112

50113
The stop command is sent by the Manager to the Proplet on the topic `m/:domain_id/c/:channel_id/control/manager/stop`
@@ -72,8 +135,6 @@ The `StopApp` function in `runtime.go` stops and cleans up a running Wasm module
72135

73136
A success message is logged with the text `"App '<AppName>' stopped successfully."` if the application stops successfully. If the application is not running or an error occurs during the stop operation, detailed error information is logged.
74137

75-
---
76-
77138
The Manager knows which Proplet is on which channel through the following mechanisms:
78139

79140
1. **Startup Notification (`create` topic):**
@@ -125,8 +186,6 @@ The Manager knows which Proplet is on which channel through the following mechan
125186

126187
These mechanisms ensure that the Manager is always aware of the active Proplets and their corresponding channels. The Manager can utilize this data to send specific control commands or monitor the Proplets effectively.
127188

128-
---
129-
130189
### **Registry Workflow**
131190

132191
1. **Proplet Fetches Wasm Binary:**

0 commit comments

Comments
 (0)