Skip to content

Commit

Permalink
feat: dynamic load wasm file(#191) (#577)
Browse files Browse the repository at this point in the history
* feat(wasm): dynamic load & update & unload wasm

* docs(wasm): update docs for wasm

* chore: code style

* chore: code style

* chore: import code style

* feat(wasm): release resources after used instance released

* refactor: refactor logic for dynamic wasm load

* fix: fix import error

* fix: fix request body error

* chore: code style

* fix: fix lint error

* fix unit test

* feat(wasm): add some tests

* chore: code style

* feat(wasm): fix actuator test and add wasm test

* feat(wasm): update wasm factory test

* feat(wasm): add wasm factory install test

* feat(wasm): update wasm factory test

* feat(wasm): improve code logic

* chore: code style

* wasm init build tag

* update import

* update import

* update import

Co-authored-by: Marco <[email protected]>
Co-authored-by: Xunzhuo <[email protected]>
Co-authored-by: seeflood <[email protected]>
  • Loading branch information
4 people authored Jul 16, 2022
1 parent 9e83f05 commit 917485d
Show file tree
Hide file tree
Showing 39 changed files with 1,085 additions and 171 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,16 @@ You can try the quickstart demos below to get started with Layotto. In addition,
| feature | status | quick start | desc |
| -------------- | :----: | :---------------------------------------------------: | -------------------------------------------------------------------- |
| Go (TinyGo) || [demo](https://mosn.io/layotto/#/en/start/wasm/start) | Compile Code written by TinyGo to \*.wasm and run in Layotto |
| Rust | TODO | TODO | Compile Code written by Rust to \*.wasm and run in Layotto |
| AssemblyScript | TODO | TODO | Compile Code written by AssemblyScript to \*.wasm and run in Layotto |
| Rust | | [demo](https://mosn.io/layotto/#/en/start/wasm/start) | Compile Code written by Rust to \*.wasm and run in Layotto |
| AssemblyScript | | [demo](https://mosn.io/layotto/#/en/start/wasm/start) | Compile Code written by AssemblyScript to \*.wasm and run in Layotto |

### As a FaaS(Serverless) runtime (Layotto + WebAssembly + k8s)

| feature | status | quick start | desc |
| -------------- | :----: | :---------------------------------------------------: | ------------------------------------------------------------------------------------------ |
| Go (TinyGo) || [demo](https://mosn.io/layotto/#/en/start/faas/start) | Compile Code written by TinyGo to \*.wasm and run in Layotto And Scheduled by k8s. |
| Rust | TODO | TODO | Compile Code written by Rust to \*.wasm and run in Layotto And Scheduled by k8s. |
| AssemblyScript | TODO | TODO | Compile Code written by AssemblyScript to \*.wasm and run in Layotto And Scheduled by k8s. |
| Rust | | [demo](https://mosn.io/layotto/#/en/start/faas/start) | Compile Code written by Rust to \*.wasm and run in Layotto And Scheduled by k8s. |
| AssemblyScript | | [demo](https://mosn.io/layotto/#/en/start/faas/start) | Compile Code written by AssemblyScript to \*.wasm and run in Layotto And Scheduled by k8s. |

## Presentations

Expand Down
4 changes: 4 additions & 0 deletions cmd/layotto/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,13 @@ import (
_ "mosn.io/pkg/buffer"

_ "mosn.io/layotto/pkg/filter/network/tcpcopy"
_ "mosn.io/layotto/pkg/filter/stream/wasm/http"
l8_grpc "mosn.io/layotto/pkg/grpc"
"mosn.io/layotto/pkg/runtime"
_ "mosn.io/layotto/pkg/wasm"
_ "mosn.io/layotto/pkg/wasm/install"
_ "mosn.io/layotto/pkg/wasm/uninstall"
_ "mosn.io/layotto/pkg/wasm/update"

_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/router/v3"
_ "mosn.io/mosn/istio/istio1106"
Expand Down
17 changes: 10 additions & 7 deletions cmd/layotto_multiple_api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,20 @@ import (
secretstore_env "github.com/dapr/components-contrib/secretstores/local/env"
secretstore_file "github.com/dapr/components-contrib/secretstores/local/file"

_ "mosn.io/layotto/pkg/filter/stream/wasm/http"
"mosn.io/layotto/pkg/grpc/default_api"
mock_state "mosn.io/layotto/pkg/mock/components/state"
secretstores_loader "mosn.io/layotto/pkg/runtime/secretstores"
_ "mosn.io/layotto/pkg/wasm"
_ "mosn.io/layotto/pkg/wasm/install"
_ "mosn.io/layotto/pkg/wasm/uninstall"
_ "mosn.io/layotto/pkg/wasm/update"

"mosn.io/layotto/components/file/local"
"mosn.io/layotto/components/file/s3/alicloud"
"mosn.io/layotto/components/file/s3/aws"
"mosn.io/layotto/components/file/s3/minio"

mock_state "mosn.io/layotto/pkg/mock/components/state"

dbindings "github.com/dapr/components-contrib/bindings"
"github.com/dapr/components-contrib/bindings/http"
"mosn.io/pkg/log"
Expand Down Expand Up @@ -154,11 +158,6 @@ import (
_ "mosn.io/mosn/pkg/wasm/runtime/wasmer"
_ "mosn.io/pkg/buffer"

_ "mosn.io/layotto/pkg/filter/network/tcpcopy"
l8_grpc "mosn.io/layotto/pkg/grpc"
"mosn.io/layotto/pkg/runtime"
_ "mosn.io/layotto/pkg/wasm"

_ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/router/v3"
_ "mosn.io/mosn/istio/istio1106"
_ "mosn.io/mosn/istio/istio1106/filter/stream/jwtauthn"
Expand Down Expand Up @@ -198,6 +197,10 @@ import (
_ "mosn.io/mosn/pkg/upstream/healthcheck"
_ "mosn.io/mosn/pkg/upstream/servicediscovery/dubbod"

_ "mosn.io/layotto/pkg/filter/network/tcpcopy"
l8_grpc "mosn.io/layotto/pkg/grpc"
"mosn.io/layotto/pkg/runtime"

helloworld_api "mosn.io/layotto/cmd/layotto_multiple_api/helloworld"
_ "mosn.io/layotto/diagnostics/exporter_iml"
)
Expand Down
27 changes: 27 additions & 0 deletions demo/faas/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,36 @@
}
}
]
},
{
"name": "wasm_filter",
"address": "0.0.0.0:34998",
"bind_port": true,
"filter_chains": [
{
"filters": [
{
"type": "proxy",
"config": {
"downstream_protocol": "Http1",
"upstream_protocol": "Http1",
"router_config_name": "wasm_router"
}
}
]
}
],
"stream_filters": [
{
"type": "wasm_filter"
}
]
}
],
"routers": [
{
"router_config_name": "wasm_router"
},
{
"router_config_name":"function_router",
"virtual_hosts":[{
Expand Down
8 changes: 4 additions & 4 deletions docs/en/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,16 @@ You can try the quickstart demos below to get started with Layotto. In addition,
| feature | status | quick start | desc |
| -------------- | :----: | :---------------------------------------------------: | -------------------------------------------------------------------- |
| Go (TinyGo) || [demo](https://mosn.io/layotto/#/en/start/wasm/start) | Compile Code written by TinyGo to \*.wasm and run in Layotto |
| Rust | TODO | TODO | Compile Code written by Rust to \*.wasm and run in Layotto |
| AssemblyScript | TODO | TODO | Compile Code written by AssemblyScript to \*.wasm and run in Layotto |
| Rust | | [demo](https://mosn.io/layotto/#/en/start/wasm/start) | Compile Code written by Rust to \*.wasm and run in Layotto |
| AssemblyScript | | [demo](https://mosn.io/layotto/#/en/start/wasm/start) | Compile Code written by AssemblyScript to \*.wasm and run in Layotto |

### As a FaaS(Serverless) runtime (Layotto + WebAssembly + k8s)

| feature | status | quick start | desc |
| -------------- | :----: | :---------------------------------------------------: | ------------------------------------------------------------------------------------------ |
| Go (TinyGo) || [demo](https://mosn.io/layotto/#/en/start/faas/start) | Compile Code written by TinyGo to \*.wasm and run in Layotto And Scheduled by k8s. |
| Rust | TODO | TODO | Compile Code written by Rust to \*.wasm and run in Layotto And Scheduled by k8s. |
| AssemblyScript | TODO | TODO | Compile Code written by AssemblyScript to \*.wasm and run in Layotto And Scheduled by k8s. |
| Rust | | [demo](https://mosn.io/layotto/#/en/start/faas/start) | Compile Code written by Rust to \*.wasm and run in Layotto And Scheduled by k8s. |
| AssemblyScript | | [demo](https://mosn.io/layotto/#/en/start/faas/start) | Compile Code written by AssemblyScript to \*.wasm and run in Layotto And Scheduled by k8s. |

## Presentations

Expand Down
6 changes: 4 additions & 2 deletions docs/en/start/faas/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ The example only needs a Redis server that can be used normally. As for where it

**Note2: Need to modify the path of the wasm file in `./demo/faas/config.json` to `/home/docker/function_1.wasm` and `/home/docker/function_2.wasm`**

**Note3: We can also load WASM file dynamically. For details, see [WASM Dynamic Load](https://mosn.io/layotto/#/en/start/wasm/start?id=dynamic-load)**

#### D、Compile & install containerd-shim-layotto-v2

```
Expand Down Expand Up @@ -101,7 +103,7 @@ sudo systemctl restart containerd
#### A、Start Layotto

```
> minikube ssh
> minikube ssh
> layotto start -c /home/docker/config.json
```

Expand Down Expand Up @@ -165,7 +167,7 @@ There are 100 inventories for book1.
The FaaS model is currently in the POC stage, and the features are not complete. It will be improved in the following aspects in the future:
1. Limit the maximum resources that can be used when the function is running, such as cpu, heap, stack, etc.
2. The functions loaded and run by different Layotto can call each other.
3. Fully integrate into the k8s ecology, such as reporting the use of resources to k8s, so that k8s can perform better scheduling.
3. Fully integrate into the k8s ecology, such as reporting the use of resources to k8s, so that k8s can perform better scheduling.
4. Add more Runtime ABI.

If you are interested in FaaS or have any questions or ideas, please leave a message in the issue area, we can build FaaS together!
49 changes: 47 additions & 2 deletions docs/en/start/wasm/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ And if it becomes like this:

![img.png](../../../img/wasm/img.png)

If developers no longer develop sdk (jar package), change to develop .wasm files and support independent upgrade and deployment, there will be no pain to push the users to upgrade.
If developers no longer develop sdk (jar package), change to develop .wasm files and support independent upgrade and deployment, there will be no pain to push the users to upgrade.

When you want to upgrade, you can release it on the operation platform. There is no need to restart the app and sidecar.

Expand All @@ -21,7 +21,7 @@ Layotto can load the compiled WASM files automatically, and interacts with them

#### step 1. start redis server and write test data

The example only needs a Redis server that can be used normally. As for where it is installed, there is no special restriction. It can be a virtual machine, a local machine or a server.
The example only needs a Redis server that can be used normally. As for where it is installed, there is no special restriction. It can be a virtual machine, a local machine or a server.

Here, we run redis with docker:

Expand Down Expand Up @@ -93,6 +93,51 @@ This http request will access the wasm module in Layotto. The wasm module will c
docker rm -f redis-test
```

### Dynamic Load

We can specify the WASM file to be loaded in `./demo/faas/config.json` config file:

```json
"config": {
"function1": {
"name": "function1",
"instance_num": 1,
"vm_config": {
"engine": "wasmer",
"path": "demo/faas/code/golang/client/function_1.wasm"
}
},
"function2": {
"name": "function2",
"instance_num": 1,
"vm_config": {
"engine": "wasmer",
"path": "demo/faas/code/golang/server/function_2.wasm"
}
}
}
```

We can also install, update, and uninstall WASM file dynamically through the following Apis.

#### Install

```shell
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name":"id_1","instance_num":2,"vm_config":{"engine":"wasmer","path":"demo/faas/code/golang/client/function_1.wasm"}}' http://127.0.0.1:34998/wasm/install
```

#### Update Instance Number

```shell
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name":"id_1","instance_num":2}' http://127.0.0.1:34998/wasm/update
```

#### Uninstall

```shell
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name":"id_1"}' http://127.0.0.1:34998/wasm/uninstall
```

### Note

This feature is still in the experimental stage, and the implementation of the WASM interactive API in the community is not uniform enough, so if you have any needs for this module, please post it in the issue area, we will build WASM together!
12 changes: 6 additions & 6 deletions docs/zh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,17 @@ Layotto 提供了多种语言版本的 SDK,SDK 通过 gRPC 与 Layotto 进行

| feature | status | quick start | desc |
| -------------- | :----: | :---------------------------------------------------: | ---------------------------------------------------------------- |
| Go (TinyGo) | | [demo](https://mosn.io/layotto/#/zh/start/wasm/start) | 把用 TinyGo 开发的代码编译成 \*.wasm 文件跑在 Layotto 上 |
| Rust | 待开发 | 待开发 | 把用 Rust 开发的代码编译成 \*.wasm 文件跑在 Layotto 上 |
| AssemblyScript | 待开发 | 待开发 | 把用 AssemblyScript 开发的代码编译成 \*.wasm 文件跑在 Layotto 上 |
| Go (TinyGo) || [demo](https://mosn.io/layotto/#/zh/start/wasm/start) | 把用 TinyGo 开发的代码编译成 \*.wasm 文件跑在 Layotto 上 |
| Rust | | [demo](https://mosn.io/layotto/#/zh/start/wasm/start) | 把用 Rust 开发的代码编译成 \*.wasm 文件跑在 Layotto 上 |
| AssemblyScript | | [demo](https://mosn.io/layotto/#/zh/start/wasm/start) | 把用 AssemblyScript 开发的代码编译成 \*.wasm 文件跑在 Layotto 上 |

### 作为 Serverless 的运行时,通过 WebAssembly (WASM) 写 FaaS

| feature | status | quick start | desc |
| -------------- | :----: | :---------------------------------------------------: | ----------------------------------------------------------------------------------------- |
| Go (TinyGo) | | [demo](https://mosn.io/layotto/#/zh/start/faas/start) | 把用 TinyGo 开发的代码编译成 \*.wasm 文件跑在 Layotto 上,并且使用 k8s 进行调度。 |
| Rust | 待开发 | 待开发 | 把用 Rust 开发的代码编译成 \*.wasm 文件跑在 Layotto 上,并且使用 k8s 进行调度。 |
| AssemblyScript | 待开发 | 待开发 | 把用 AssemblyScript 开发的代码编译成 \*.wasm 文件跑在 Layotto 上,并且使用 k8s 进行调度。 |
| Go (TinyGo) || [demo](https://mosn.io/layotto/#/zh/start/faas/start) | 把用 TinyGo 开发的代码编译成 \*.wasm 文件跑在 Layotto 上,并且使用 k8s 进行调度。 |
| Rust | | [demo](https://mosn.io/layotto/#/zh/start/faas/start) | 把用 Rust 开发的代码编译成 \*.wasm 文件跑在 Layotto 上,并且使用 k8s 进行调度。 |
| AssemblyScript | | [demo](https://mosn.io/layotto/#/zh/start/faas/start) | 把用 AssemblyScript 开发的代码编译成 \*.wasm 文件跑在 Layotto 上,并且使用 k8s 进行调度。 |

## Landscapes

Expand Down
10 changes: 6 additions & 4 deletions docs/zh/start/faas/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Layotto支持加载并运行以 wasm 为载体的 Function,并支持Function
### 三、环境搭建

#### A、安装&运行 Redis

这里只是需要一个可以正常使用 Redis 即可,至于 Redis 安装在哪里没有特别限制,可以是虚拟机里,也可以是本机或者服务器,这里以安装在 mac 为例进行介绍。

```
Expand Down Expand Up @@ -59,6 +59,8 @@ Layotto支持加载并运行以 wasm 为载体的 Function,并支持Function

**注2:需要把`./demo/faas/config.json`中的 wasm 文件的路径修改为`/home/docker/function_1.wasm``/home/docker/function_2.wasm`, 两个wasm文件在后面会被自动注入。**

**注3:也可动态加载 WASM 文件,详情参见:[WASM 动态注册](https://mosn.io/layotto/#/zh/start/wasm/start?id=动态注册)**

#### D、安装 containerd-shim-layotto-v2

```
Expand Down Expand Up @@ -101,7 +103,7 @@ sudo systemctl restart containerd
#### A、启动 Layotto

```
> minikube ssh
> minikube ssh
> layotto start -c /home/docker/config.json
```

Expand Down Expand Up @@ -159,15 +161,15 @@ There are 100 inventories for book1.
2.启动Layotto时,redis连接失败,打印 "occurs an error: redis store: error connecting to redis at":

检查redis的配置,看是否redis配置错误造成的。



### 说明

目前整套 FaaS 模型处于 POC 阶段,功能还不够完善,后续会在以下几个方向上进一步探索完善:
1. 对函数运行时可使用的最大资源进行限制,如cpu,heap,stack等。
2. 由不同 Layotto 加载运行的函数之间可以互相调用。
3. 充分融入k8s生态,比如上报使用资源给k8s,让k8s进行更好的调度。
3. 充分融入k8s生态,比如上报使用资源给k8s,让k8s进行更好的调度。
4. 增加更多的 Runtime ABI。

如果你对 FaaS 感兴趣或者有任何疑问或者想法,欢迎在 issue 区留言,我们一起建设 FaaS !
47 changes: 46 additions & 1 deletion docs/zh/start/wasm/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Layotto支持加载编译好的WASM文件,并通过`proxy_abi_version_0_2_0`
docker run -d --name redis-test -p 6379:6379 redis
```

调用 Redis 容器中的 redis-cli,执行`set book1 100`
调用 Redis 容器中的 redis-cli,执行`set book1 100`

```shell
docker exec -i redis-test redis-cli set book1 100
Expand Down Expand Up @@ -90,6 +90,51 @@ There are 100 inventories for book1.
docker rm -f redis-test
```

### 动态注册

除了在 `./demo/faas/config.json` 中指定要加载的 WASM 文件外(比如以下配置):

```json
"config": {
"function1": {
"name": "function1",
"instance_num": 1,
"vm_config": {
"engine": "wasmer",
"path": "demo/faas/code/golang/client/function_1.wasm"
}
},
"function2": {
"name": "function2",
"instance_num": 1,
"vm_config": {
"engine": "wasmer",
"path": "demo/faas/code/golang/server/function_2.wasm"
}
}
}
```

我们也可通过以下接口来动态的加载、更新、卸载 WASM 文件。

#### 加载

```shell
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name":"id_1","instance_num":2,"vm_config":{"engine":"wasmer","path":"demo/faas/code/golang/client/function_1.wasm"}}' http://127.0.0.1:34998/wasm/install
```

#### 更新实例数

```shell
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name":"id_1","instance_num":2}' http://127.0.0.1:34998/wasm/update
```

#### 卸载

```shell
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name":"id_1"}' http://127.0.0.1:34998/wasm/uninstall
```

### 说明

该功能目前仍处于试验阶段,社区里对于WASM跟宿主的交互API也不够统一,因此如果您有该模块的需求欢迎发表在issue区,我们一起建设WASM!
Loading

0 comments on commit 917485d

Please sign in to comment.