-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Brooks Townsend <brooksmtownsend@gmail.com>
- Loading branch information
1 parent
37eb8d3
commit 1e2cc4d
Showing
69 changed files
with
6,821 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,14 @@ | ||
# wasmCloud-contrib | ||
|
||
Community contributions of providers, components, and demos | ||
|
||
## Components | ||
|
||
- [moonbit/http-hello-world](./components/moonbit/http-hello-world/) is an example component that implements the `wasi-http/incoming-handler@0.2.0` interface and is built with [Moonbit](https://www.moonbitlang.com/) | ||
|
||
## Secrets | ||
|
||
There are currently two implementations of [wasmCloud secrets backends](https://wasmcloud.com/docs/deployment/security/secrets#implementing-a-secrets-backend) available in this repository. | ||
|
||
- [secrets-kubernetes](./secrets/secrets-kubernetes/) for using secrets stored in Kubernetes in wasmCloud applications | ||
- [secrets-vault](./secrets/secrets-vault/) for using secrets stored in Vault in wasmCloud applications |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build/*.wasm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# Moonbit http-bello-world | ||
|
||
This example was created following the [Developing Wasm component model in MoonBit with minimal output size](https://www.moonbitlang.com/blog/component-model) blog. | ||
|
||
## Prerequisites | ||
|
||
- [Rust toolchain](https://www.rust-lang.org/tools/install) to install prerequisites | ||
- wit-deps | ||
- `cargo install wit-deps-cli` | ||
- wasm-tools | ||
- `cargo install wasm-tools` | ||
- Moonbit wit-bindgen fork | ||
- `cargo install wit-bindgen-cli --git https://github.com/peter-jerry-ye/wit-bindgen/ --branch moonbit` | ||
- [Moonbit CLI](https://www.moonbitlang.com/download/#moonbit-cli-tools) | ||
- [wash CLI](https://wasmcloud.com/docs/installation) | ||
|
||
## Run in wasmCloud | ||
|
||
After the tutorial and running the Moonbit Wasm component in wasmtime, we created a `wasmcloud.toml` to encapsulate the build & adapt steps and a `wadm.yaml` for running the component in wasmCloud. | ||
|
||
The `wadm.yaml` was created using [wit2wadm](https://github.com/brooksmtownsend/wit2wadm). You can install the `wit2wadm` plugin using `wash plugin install oci://ghcr.io/brooksmtownsend/wit2wadm:0.2.0`. | ||
|
||
```bash | ||
wash build | ||
wash wit2wadm ./build/gen.wasm --name moonbit-http --description "HTTP hello world demo with a component written in Moonbit" > wadm.yaml | ||
wash up -d | ||
wash app deploy ./wadm.yaml | ||
``` | ||
|
||
Then, once the application is in the `Deployed` status: | ||
|
||
```bash | ||
> curl localhost:8000 | ||
Hello, World% | ||
``` | ||
|
||
## Size & Speed | ||
|
||
As promised, the Moonbit component is tiny! | ||
|
||
```bash | ||
➜ ll build | ||
Permissions Size User Date Modified Name | ||
.rw-r--r-- 22k brooks 7 Aug 10:30 gen.wasm | ||
``` | ||
|
||
Running 100 max instances of the moonbit component, we get impressive numbers for HTTP throughput. As Moonbit evolves, it will be interesting to see how viable the language is for creating performant components. | ||
|
||
```bash | ||
➜ hey -z 20s -c 100 http://localhost:8000 | ||
|
||
Summary: | ||
Total: 20.0071 secs | ||
Slowest: 0.0401 secs | ||
Fastest: 0.0009 secs | ||
Average: 0.0048 secs | ||
Requests/sec: 20901.9356 | ||
|
||
|
||
Response time histogram: | ||
0.001 [1] | | ||
0.005 [238066] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | ||
0.009 [176898] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | ||
0.013 [2474] | | ||
0.017 [384] | | ||
0.021 [140] | | ||
0.024 [95] | | ||
0.028 [81] | | ||
0.032 [47] | | ||
0.036 [0] | | ||
0.040 [1] | | ||
|
||
|
||
Latency distribution: | ||
10% in 0.0035 secs | ||
25% in 0.0040 secs | ||
50% in 0.0047 secs | ||
75% in 0.0054 secs | ||
90% in 0.0061 secs | ||
95% in 0.0067 secs | ||
99% in 0.0084 secs | ||
|
||
Details (average, fastest, slowest): | ||
DNS+dialup: 0.0000 secs, 0.0009 secs, 0.0401 secs | ||
DNS-lookup: 0.0000 secs, 0.0000 secs, 0.0017 secs | ||
req write: 0.0000 secs, 0.0000 secs, 0.0009 secs | ||
resp wait: 0.0046 secs, 0.0007 secs, 0.0400 secs | ||
resp read: 0.0002 secs, 0.0000 secs, 0.0140 secs | ||
|
||
Status code distribution: | ||
[200] 418187 responses | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/sh | ||
|
||
moon build --target wasm | ||
wasm-tools component embed wit target/wasm/release/build/gen/gen.wasm -o target/wasm/release/build/gen/gen.wasm --encoding utf16 | ||
wasm-tools component new target/wasm/release/build/gen/gen.wasm -o target/wasm/release/build/gen/gen.wasm |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
|
||
pub extern "wasm" fn extend16(value : Int) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 i32.extend16_s) | ||
|
||
pub extern "wasm" fn extend8(value : Int) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 i32.extend8_s) | ||
|
||
pub extern "wasm" fn store8(offset : Int, value : Int) = | ||
#|(func (param i32) (param i32) local.get 0 local.get 1 i32.store8) | ||
|
||
pub extern "wasm" fn load8_u(offset : Int) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 i32.load8_u) | ||
|
||
pub extern "wasm" fn load8(offset : Int) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 i32.load8_s) | ||
|
||
pub extern "wasm" fn store16(offset : Int, value : Int) = | ||
#|(func (param i32) (param i32) local.get 0 local.get 1 i32.store16) | ||
|
||
pub extern "wasm" fn load16(offset : Int) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 i32.load16_s) | ||
|
||
pub extern "wasm" fn load16_u(offset : Int) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 i32.load16_u) | ||
|
||
pub extern "wasm" fn store32(offset : Int, value : Int) = | ||
#|(func (param i32) (param i32) local.get 0 local.get 1 i32.store) | ||
|
||
pub extern "wasm" fn load32(offset : Int) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 i32.load) | ||
|
||
pub extern "wasm" fn store64(offset : Int, value : Int64) = | ||
#|(func (param i32) (param i64) local.get 0 local.get 1 i64.store) | ||
|
||
pub extern "wasm" fn load64(offset : Int) -> Int64 = | ||
#|(func (param i32) (result i64) local.get 0 i64.load) | ||
|
||
pub extern "wasm" fn storef32(offset : Int, value : Float) = | ||
#|(func (param i32) (param f32) local.get 0 local.get 1 f32.store) | ||
|
||
pub extern "wasm" fn loadf32(offset : Int) -> Float = | ||
#|(func (param i32) (result f32) local.get 0 f32.load) | ||
|
||
pub extern "wasm" fn storef64(offset : Int, value : Double) = | ||
#|(func (param i32) (param f64) local.get 0 local.get 1 f64.store) | ||
|
||
pub extern "wasm" fn loadf64(offset : Int) -> Double = | ||
#|(func (param i32) (result f64) local.get 0 f64.load) | ||
|
||
pub extern "wasm" fn f32_to_i32(value : Float) -> Int = | ||
#|(func (param f32) (result i32) local.get 0 f32.convert_i32_s) | ||
|
||
pub extern "wasm" fn i32_to_f32(value : Int) -> Float = | ||
#|(func (param i32) (result f32) local.get 0 i32.trunc_f32_s) | ||
|
||
pub extern "wasm" fn f32_to_i64(value : Float) -> Int64 = | ||
#|(func (param f32) (result i64) local.get 0 f32.convert_i64_s) | ||
|
||
pub extern "wasm" fn i64_to_f32(value : Int64) -> Float = | ||
#|(func (param i64) (result f32) local.get 0 i64.trunc_f32_s) | ||
|
||
pub extern "wasm" fn f32_to_f64(value : Float) -> Double = | ||
#|(func (param f32) (result f64) local.get 0 f64.promote_f32) | ||
|
||
pub extern "wasm" fn f64_to_f32(value : Double) -> Float = | ||
#|(func (param f64) (result f32) local.get 0 f32.demote_f64) | ||
|
||
extern "wasm" fn malloc_inline(size : Int) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 call $moonbit.malloc) | ||
|
||
pub fn malloc(size : Int) -> Int { | ||
let words = size / 4 + 1 | ||
let address = malloc_inline(8 + words * 4) | ||
store32(address, 1) | ||
store32(address + 4, words.lsl(8).lor(246)) | ||
store8(address + words * 4 + 7, 3 - size % 4) | ||
address + 8 | ||
} | ||
|
||
pub extern "wasm" fn free(position : Int) = | ||
#|(func (param i32) local.get 0 i32.const 8 i32.sub call $moonbit.decref) | ||
|
||
pub fn copy(dest : Int, src : Int) -> Unit { | ||
let src = src - 8 | ||
let dest = dest - 8 | ||
let src_len = load32(src + 4).land(0xFFFFFF) | ||
let dest_len = load32(dest + 4).land(0xFFFFFF) | ||
let min = if src_len < dest_len { src_len } else { dest_len } | ||
copy_inline(dest, src, min) | ||
} | ||
|
||
extern "wasm" fn copy_inline(dest : Int, src : Int, len : Int) = | ||
#|(func (param i32) (param i32) (param i32) local.get 0 local.get 1 local.get 2 memory.copy) | ||
|
||
pub extern "wasm" fn str2ptr(str : String) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 call $moonbit.decref local.get 0 i32.const 8 i32.add) | ||
|
||
pub extern "wasm" fn ptr2str(ptr : Int) -> String = | ||
#|(func (param i32) (result i32) local.get 0 i32.const 4 i32.sub i32.const 243 i32.store8 local.get 0 i32.const 8 i32.sub) | ||
|
||
pub extern "wasm" fn bytes2ptr(bytes : Bytes) -> Int = | ||
#|(func (param i32) (result i32) local.get 0 call $moonbit.decref local.get 0 i32.const 8 i32.add) | ||
|
||
pub extern "wasm" fn ptr2bytes(ptr : Int) -> Bytes = | ||
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) | ||
|
||
pub trait Any {} | ||
pub struct Cleanup { | ||
address : Int | ||
size : Int | ||
align : Int | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
|
||
pub fn cabi_realloc( | ||
src_offset : Int, | ||
src_size : Int, | ||
_dst_alignment : Int, | ||
dst_size : Int | ||
) -> Int { | ||
// malloc | ||
if src_offset == 0 && src_size == 0 { | ||
return @ffi.malloc(dst_size) | ||
} | ||
// free | ||
if dst_size <= 0 { | ||
@ffi.free(src_offset) | ||
return 0 | ||
} | ||
// realloc | ||
let dst = @ffi.malloc(dst_size) | ||
@ffi.copy(dst, src_offset) | ||
@ffi.free(src_offset) | ||
dst | ||
} | ||
|
8 changes: 8 additions & 0 deletions
8
...ents/moonbit/http-hello-world/gen/interface_exports_wasi_http_incoming_handler_export.mbt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Generated by `wit-bindgen` 0.29.0. DO NOT EDIT! | ||
|
||
pub fn wasmExportHandle(p0 : Int, p1 : Int) -> Unit { | ||
|
||
let _ = @incomingHandler.handle(@types.IncomingRequest::IncomingRequest(p0), @types.ResponseOutparam::ResponseOutparam(p1)); | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
{ | ||
"link": { | ||
"wasm": { | ||
"exports": ["cabi_realloc:cabi_realloc", "wasmExportHandle:wasi:http/incoming-handler@0.2.0#handle"], | ||
"export-memory-name": "memory", | ||
"heap-start-address": 0 | ||
} | ||
} | ||
,"import": [{ "path" : "wasmcloud/example/ffi", "alias" : "ffi" }, { "path" : "wasmcloud/example/interface/exports/wasi/http/incomingHandler", "alias" : "incomingHandler" }, { "path" : "wasmcloud/example/interface/imports/wasi/http/types", "alias" : "types" }] | ||
} |
2 changes: 2 additions & 0 deletions
2
components/moonbit/http-hello-world/gen/worlds_server_export.mbt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Generated by `wit-bindgen` 0.29.0. DO NOT EDIT! | ||
|
2 changes: 2 additions & 0 deletions
2
.../moonbit/http-hello-world/interface/exports/wasi/http/incomingHandler/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
This interface defines a handler of incoming HTTP Requests. It should | ||
be exported by components which can respond to HTTP Requests. |
9 changes: 9 additions & 0 deletions
9
...onents/moonbit/http-hello-world/interface/exports/wasi/http/incomingHandler/moon.pkg.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"import": [ | ||
{ | ||
"path": "wasmcloud/example/interface/imports/wasi/http/types", | ||
"alias": "types" | ||
}, | ||
"wasmcloud/example/interface/imports/wasi/io/streams" | ||
] | ||
} |
32 changes: 32 additions & 0 deletions
32
components/moonbit/http-hello-world/interface/exports/wasi/http/incomingHandler/top.mbt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Generated by `wit-bindgen` 0.28.0. DO NOT EDIT! | ||
/// This function is invoked with an incoming HTTP Request, and a resource | ||
/// `response-outparam` which provides the capability to reply with an HTTP | ||
/// Response. The response is sent by calling the `response-outparam.set` | ||
/// method, which allows execution to continue after the response has been | ||
/// sent. This enables both streaming to the response body, and performing other | ||
/// work. | ||
/// | ||
/// The implementor of this function must write a response to the | ||
/// `response-outparam` before returning, or else the caller will respond | ||
/// with an error on its behalf. | ||
pub fn handle( | ||
request : @types.IncomingRequest, | ||
response_out : @types.ResponseOutparam | ||
) -> Unit { | ||
let response = match request.path_with_query() { | ||
None | Some("/") => make_response(b"Hello, World") | ||
_ => make_response(b"Not Found", status_code=404) | ||
} | ||
|> Ok | ||
response_out.set(response) | ||
} | ||
|
||
fn make_response( | ||
body : Bytes, | ||
~status_code : UInt = 200 | ||
) -> @types.OutgoingResponse { | ||
let response = @types.outgoing_response(@types.fields()) | ||
response.body().unwrap().write().unwrap().blocking_write_and_flush(body).unwrap() | ||
response.set_status_code(status_code).unwrap() | ||
response | ||
} |
8 changes: 8 additions & 0 deletions
8
...moonbit/http-hello-world/interface/imports/wasi/clocks/monotonicClock/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
WASI Monotonic Clock is a clock API intended to let users measure elapsed | ||
time. | ||
|
||
It is intended to be portable at least between Unix-family platforms and | ||
Windows. | ||
|
||
A monotonic clock is a clock which has an unspecified initial value, and | ||
successive reads of the clock will produce non-decreasing values. |
9 changes: 9 additions & 0 deletions
9
...nents/moonbit/http-hello-world/interface/imports/wasi/clocks/monotonicClock/moon.pkg.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"import": [ | ||
{ "path": "wasmcloud/example/ffi", "alias": "ffi" }, | ||
{ | ||
"path": "wasmcloud/example/interface/imports/wasi/io/poll", | ||
"alias": "poll" | ||
} | ||
] | ||
} |
38 changes: 38 additions & 0 deletions
38
components/moonbit/http-hello-world/interface/imports/wasi/clocks/monotonicClock/top.mbt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Generated by `wit-bindgen` 0.28.0. DO NOT EDIT! | ||
fn wasmImportNow() -> Int64 = "wasi:clocks/monotonic-clock@0.2.0" "now" | ||
|
||
/// Read the current value of the clock. | ||
/// | ||
/// The clock is monotonic, therefore calling this function repeatedly will | ||
/// produce a sequence of non-decreasing values. | ||
pub fn now() -> UInt64 { | ||
let result : Int64 = wasmImportNow() | ||
return result.to_uint64() | ||
} | ||
|
||
fn wasmImportResolution() -> Int64 = "wasi:clocks/monotonic-clock@0.2.0" "resolution" | ||
|
||
/// Query the resolution of the clock. Returns the duration of time | ||
/// corresponding to a clock tick. | ||
pub fn resolution() -> UInt64 { | ||
let result : Int64 = wasmImportResolution() | ||
return result.to_uint64() | ||
} | ||
|
||
fn wasmImportSubscribeInstant(p0 : Int64) -> Int = "wasi:clocks/monotonic-clock@0.2.0" "subscribe-instant" | ||
|
||
/// Create a `pollable` which will resolve once the specified instant | ||
/// has occurred. | ||
pub fn subscribe_instant(when : UInt64) -> @poll.Pollable { | ||
let result : Int = wasmImportSubscribeInstant(when.to_int64()) | ||
return @poll.Pollable::Pollable(result) | ||
} | ||
|
||
fn wasmImportSubscribeDuration(p0 : Int64) -> Int = "wasi:clocks/monotonic-clock@0.2.0" "subscribe-duration" | ||
|
||
/// Create a `pollable` that will resolve after the specified duration has | ||
/// elapsed from the time this function is invoked. | ||
pub fn subscribe_duration(when : UInt64) -> @poll.Pollable { | ||
let result : Int = wasmImportSubscribeDuration(when.to_int64()) | ||
return @poll.Pollable::Pollable(result) | ||
} |
3 changes: 3 additions & 0 deletions
3
components/moonbit/http-hello-world/interface/imports/wasi/http/types/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
This interface defines all of the types and methods for implementing | ||
HTTP Requests and Responses, both incoming and outgoing, as well as | ||
their headers, trailers, and bodies. |
Oops, something went wrong.