├── .gitignore ├── Cargo.toml ├── Dockerfile ├── README-zh.md ├── README.md ├── cloud ├── bootstrap ├── config.json ├── hello_bg.wasm ├── serverless.yaml └── ssvm ├── docs ├── deploy01.png ├── deploy01_cn.png ├── deploy02.png ├── deploy02_cn.png ├── deploy03.png ├── deploy03_cn.png ├── docker_command.md ├── result.png ├── result_cn.png ├── test.png └── test_cn.png └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello" 3 | version = "0.1.0" 4 | authors = ["ubuntu"] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | wasm-bindgen = "=0.2.61" 9 | serde = { version = "1.0", features = ["derive"] } 10 | serde_json = "=1.0.44" 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | ARG DEBIAN_FRONTEND=noninteractive 3 | RUN apt-get update \ 4 | && apt-get -y upgrade \ 5 | && apt install -y build-essential libboost-all-dev llvm-dev liblld-10-dev \ 6 | && apt install -y curl wget git vim pkg-config libssl-dev 7 | RUN wget https://www.secondstate.io/download/ssvm-0.6.9.tar.gz \ 8 | && tar -xzf ssvm-0.6.9.tar.gz 9 | RUN wget https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-gpu-linux-x86_64-1.15.0.tar.gz \ 10 | && tar -C /usr/ -xzf libtensorflow-gpu-linux-x86_64-1.15.0.tar.gz 11 | RUN wget https://www.secondstate.io/download/commands-0.1.0.tar.gz \ 12 | && tar -C /usr/local/bin/ -xzf commands-0.1.0.tar.gz 13 | 14 | # Switch back to dialog for any ad-hoc use of apt-get 15 | ENV DEBIAN_FRONTEND=dialog 16 | -------------------------------------------------------------------------------- /README-zh.md: -------------------------------------------------------------------------------- 1 | # 腾讯云的Rust和WebAssembly函数即服务 2 | 3 | ## 先决条件 4 | 5 | 如果还没有前期的安装,按照下面的简要步骤在你的电脑上[安装 ssvmup](https://www.secondstate.io/articles/ssvmup/)。 6 | 7 | ## 创建 WASM bytecode 8 | 9 | 我们创建了 [Rust 函数即服务](src/main.rs)。它只是从 STDIN 获取函数输入,并将结果输出到 STDOUT 中。这使得它可以在各种不同的场合和有效载荷中使用。该函数使用‘ key1’和‘ key2’字段预测输入 JSON 字符串。正如我们将看到的,这就是腾讯云内置的 hello world 测试中使用的 JSON 格式。 10 | 11 | 要将 Rust 函数构建到 WebAssembly 字节码应用程序中,请从命令行执行以下操作。它可能需要几分钟时间来创建。 12 | 13 | ``` 14 | $ ssvmup build 15 | ``` 16 | 17 | ## 部署包 18 | 19 | ``` 20 | $ cp pkg/hello_bg.wasm cloud/ 21 | $ cd cloud 22 | $ zip hello.zip * 23 | ``` 24 | 25 | ## 部署在腾讯云上 26 | 27 | 0 点击控制台 https://cloud.tencent.com/ 28 | 29 | 1 点击 云产品 | 无服务云函数 | 函数服务 | 创建 30 | 31 | 2 运行环境, 从下拉列表选择 CustomRuntime 32 | 33 | 3 选择空白模板函数 34 | 35 | 4 点击下一步 36 | 37 | ![部署步骤 1](docs/deploy01_cn.png) 38 | 39 | 5 将执行处理程序设置为 `hello_bg.wasm` 40 | 41 | 6 为 Submitting Method 选择“ Local zip file” ,然后上传“ hello.zip”文件 42 | 43 | 7 点击完成 44 | 45 | ![部署步骤 2](docs/deploy02_cn.png) 46 | 47 | ## 测试 48 | 49 | 成功部署函数后,转到 函数代码 选项卡。 50 | 51 | ![部署成功](docs/deploy03_cn.png) 52 | 53 | 向下滚动并单击测试按钮。该函数将接收 hello world JSON 数据输入 54 | ``` 55 | { 56 | "key1": "test value 1", 57 | "key2": "test value 2" 58 | } 59 | ``` 60 | 61 | ![测试该函数](docs/test_cn.png) 62 | 63 | 并输出一个 hello 消息。 64 | 65 | ``` 66 | Hello! test value 1, test value 2 67 | ``` 68 | 69 | ![测试执行结果](docs/result_cn.png) 70 | 71 | 就是这样! 您现在已经测试并部署了第一个服务器端 WebAssembly 函数! 72 | 73 | ## 下一步 74 | 75 | 下一步是 [创建一个完整的演示来运行,并可视化一个机器学习算法](https://github.com/second-state/wasm-learning/tree/master/tencentcloud/ssvm/pca). 76 | 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [中文文档点击这里](README-zh.md) 2 | 3 | --- 4 | 5 | # Rust and WebAssembly Function as a Service (FaaS) on Tencent Cloud 6 | 7 | ## Prerequisites 8 | 9 | If you have not done so already, follow these simple instructions to [install ssvmup](https://www.secondstate.io/articles/ssvmup/) on your development computer. 10 | 11 | ## Build the WASM bytecode 12 | 13 | We build a [Rust function as a service](src/main.rs). It simply takes the function input from STDIN and outputs the results into STDOUT. That allows it to be used in a variety of different scenarions and payloads. The function anticipates an input JSON string with `key1` and `key2` fields. As we will see that is the JSON format used in TencentCloud's built-in hello world tests. 14 | 15 | To build the Rust function into a WebAssembly bytecode application, do the following from your command line. It might take a few minutes to build. 16 | 17 | ``` 18 | $ ssvmup build 19 | ``` 20 | 21 | ## Package for deployment 22 | 23 | ``` 24 | $ cp pkg/hello_bg.wasm cloud/ 25 | $ cd cloud 26 | $ zip hello.zip * 27 | ``` 28 | 29 | ## Deploy on TencentCloud 30 | 31 | 0 Go to the console https://cloud.tencent.com/?lang=en 32 | 33 | 1 Go to Products | Serverless Cloud Function | Function Service | Create 34 | 35 | 2 For Create Method, select CustomRuntime from the dropdown list 36 | 37 | 3 Select the Empty function template 38 | 39 | 4 Click on Next 40 | 41 | ![Deploy step 1](docs/deploy01.png) 42 | 43 | 5 Set the Execution handler to `hello_bg.wasm` 44 | 45 | 6 Select "Local zip file" for Submitting Method, and then upload the `hello.zip` file 46 | 47 | 7 Click on Complete 48 | 49 | ![Deploy step 2](docs/deploy02.png) 50 | 51 | ## Test 52 | 53 | Once the function is successfully deployed, go to the Function code tab. 54 | 55 | ![Deploy success](docs/deploy03.png) 56 | 57 | Scroll down and click on the Test button. The function will take the hello world JSON data input 58 | 59 | ``` 60 | { 61 | "key1": "test value 1", 62 | "key2": "test value 2" 63 | } 64 | ``` 65 | 66 | ![Test the function](docs/test.png) 67 | 68 | and output a hello message. 69 | 70 | ``` 71 | Hello! test value 1, test value 2 72 | ``` 73 | 74 | ![Test execution result](docs/result.png) 75 | 76 | That's it! You have now tested and deployed your first server-side WebAssembly function! 77 | 78 | ## Next step 79 | 80 | The next step is to [create a complete demo to run and visualize a machine learning algorithm](https://github.com/second-state/wasm-learning/tree/master/tencentcloud/ssvm/pca). 81 | 82 | -------------------------------------------------------------------------------- /cloud/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | # Initialization - load function handler 6 | # source ./"$(echo $_HANDLER | cut -d. -f1).sh" 7 | 8 | # Info custom runtime ready 9 | curl -d " " -X POST -s "http://$SCF_RUNTIME_API:$SCF_RUNTIME_API_PORT/runtime/init/ready" 10 | 11 | # Processing 12 | while true 13 | do 14 | HEADERS="$(mktemp)" 15 | # Get an event. The HTTP request will block until one is received 16 | EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET -s "http://$SCF_RUNTIME_API:$SCF_RUNTIME_API_PORT/runtime/invocation/next") 17 | 18 | # Execute the handler function from the script 19 | # RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) <<< "$EVENT_DATA") 20 | RESPONSE=$(./ssvm "$_HANDLER" <<< "$EVENT_DATA") 21 | 22 | # Send the response 23 | curl -X POST -s "http://$SCF_RUNTIME_API:$SCF_RUNTIME_API_PORT/runtime/invocation/response" -d "$RESPONSE" 24 | done 25 | -------------------------------------------------------------------------------- /cloud/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "serverless-cloud-function-application": { 3 | "application":{ 4 | "Chinese":{ 5 | "name": "WebAssembly函数示例", 6 | "description": "本示例展示如何在CustomRuntime类型函数中使用Rust写的WebAssembly函数。", 7 | "attention": "无", 8 | "readme": { 9 | "file": "", 10 | "content": "请参见: https://github.com/second-state/ssvm-tencent-starter/blob/master/README-zh.md" 11 | }, 12 | "license": { 13 | "file": "", 14 | "content": "公开" 15 | }, 16 | "author": { 17 | "name": "Second State | 第二形科技" 18 | } 19 | }, 20 | "English":{ 21 | "name": "rust_webassembly_demo", 22 | "description": "This example shows how to use WebAssembly functions written in Rust in CustomRuntime", 23 | "attention": "No", 24 | "readme": { 25 | "file": "", // readme file 26 | "content": "Please checkout: https://github.com/second-state/ssvm-tencent-starter/blob/master/README.md" //content of readme 27 | }, 28 | "license": { 29 | "file": "", // license file 30 | "content": "Open" //content of license 31 | }, 32 | "author": { 33 | "name": "Second State" // author 34 | } 35 | }, 36 | "input_parameters":{ 37 | "event":"", 38 | "context":"" 39 | }, 40 | "output_parameters":{ 41 | }, 42 | "download_address":"https://github.com/second-state/ssvm-tencent-starter", //Demo's git download url. demo的git下载链接 43 | "tags":[ 44 | "CustomRuntime", "Rust", "WebAssembly" 45 | // The tags only support English and can be multiple, we suggest you to use keywords such as runtime, trigger, environment and so on. 46 | // 标签统一为英文,可编写多个,建议使用runtime、触发器、场景等关键字,用户可以通过该关键字搜索。前台需要展示,请认真填写,不支持中文 47 | ], 48 | "version": "1.0.0" 49 | // Version number, which identifies the demo version status. 50 | // Demo will not to update to the page if the version number unmodified. 51 | //版本号,通过版本号标识 demo 升级情况,未修改版本号会导致 demo 不更新至页面 52 | }, 53 | "functions": { 54 | "name": "WebAssemblyDemo", // Function name which only be in English. 函数名称,只支持英文 55 | "description": "Rust and WebAssembly demo function. Rust and WebAssembly 模版函数", 56 | "handler":"hello_bg.wasm", 57 | "memorySize": 128, // Running memory. 运行配置内存 58 | "timeout": 3, // Running timeout. 运行超时时间 59 | "runtime": "CustomRuntime", // Runtime which users can search demo by this keyword. 运行环境,用户可以通过该关键字搜索["Python2.7", "Python3.6", "Nodejs6.10", "Java8", "LuaCDN", "NodejsCDN", "Php5", "Php7", "Nodejs8.9", "Go1", "CustomRuntime"] 60 | "Environment":{ 61 | }, // Optional, used to define environment variables. 可选,用于定义环境变量 62 | "Events":{ 63 | }, // Optional, used define the event source that triggers this function. 可选,用于定义触发此函数的事件源 64 | "VpcConfig":{ 65 | }, // Optional, used configure cloud function's private network. 可选, 用于配置云函数访问 VPC 私有网络。 66 | "codeObject": { 67 | "codeFile": [ 68 | "bootstrap", 69 | "ssvm", 70 | "hello_bg.wasm" 71 | ], 72 | "CodeUri":[ // Code download url which should be same as 'download_address'. 代码下载地址,和download_address保持一致 73 | "https://github.com/second-state/ssvm-tencent-starter" 74 | ] 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /cloud/hello_bg.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/cloud/hello_bg.wasm -------------------------------------------------------------------------------- /cloud/serverless.yaml: -------------------------------------------------------------------------------- 1 | component: scf 2 | name: ap-guangzhou_wasm_demo 3 | org: app 4 | app: WebAssemblyDemo 5 | stage: dev 6 | inputs: 7 | name: WebAssemblyDemo 8 | src: ./ 9 | description: Rust and WebAssembly template function 模板函数 10 | handler: hello_bg.wasm 11 | runtime: CustomRuntime 12 | namespace: default 13 | region: ap-guangzhou 14 | memorySize: 128 15 | timeout: 3 16 | -------------------------------------------------------------------------------- /cloud/ssvm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/cloud/ssvm -------------------------------------------------------------------------------- /docs/deploy01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/deploy01.png -------------------------------------------------------------------------------- /docs/deploy01_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/deploy01_cn.png -------------------------------------------------------------------------------- /docs/deploy02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/deploy02.png -------------------------------------------------------------------------------- /docs/deploy02_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/deploy02_cn.png -------------------------------------------------------------------------------- /docs/deploy03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/deploy03.png -------------------------------------------------------------------------------- /docs/deploy03_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/deploy03_cn.png -------------------------------------------------------------------------------- /docs/docker_command.md: -------------------------------------------------------------------------------- 1 | Build and tag the Docker image from the repo root directory. 2 | 3 | ``` 4 | $ docker build -t ssvm-0.6.9 . 5 | ``` 6 | 7 | Confirm that our image is created and tagged. 8 | 9 | ``` 10 | $ docker images 11 | REPOSITORY TAG IMAGE ID CREATED SIZE 12 | ssvm-0.6.9 latest 9e7ab8a800d5 34 seconds ago 2.04GB 13 | ubuntu 20.04 9140108b62dc 2 weeks ago 72.9MB 14 | ``` 15 | 16 | Start Docker with local mapping 17 | 18 | ``` 19 | $ docker run --rm -it -v $(pwd):/app ssvm-0.6.9 20 | ``` 21 | 22 | Compile 23 | 24 | ``` 25 | root@fed06e527d57:/# ./ssvmc app/cloud/hello_bg.wasm hello.so 26 | 2020-10-16 09:38:20,780 INFO [default] compile start 27 | 2020-10-16 09:38:20,800 INFO [default] verify start 28 | 2020-10-16 09:38:20,817 INFO [default] optimize start 29 | 2020-10-16 09:38:25,747 INFO [default] codegen start 30 | 2020-10-16 09:38:28,057 INFO [default] compile done 31 | ``` 32 | 33 | Run 34 | 35 | ``` 36 | root@fed06e527d57:/# echo '{"key1":"123","key2":"abc"}' | ./ssvmr hello.so 37 | Hello! 123, abc 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /docs/result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/result.png -------------------------------------------------------------------------------- /docs/result_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/result_cn.png -------------------------------------------------------------------------------- /docs/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/test.png -------------------------------------------------------------------------------- /docs/test_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-tencent-starter/6f37b13e2894cf9715aa5032397b5ff3503d1422/docs/test_cn.png -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, Read}; 2 | use serde::Deserialize; 3 | 4 | fn main() { 5 | let mut buffer = String::new(); 6 | io::stdin().read_to_string(&mut buffer).expect("Error reading from STDIN"); 7 | let obj: FaasInput = serde_json::from_str(&buffer).unwrap(); 8 | let key1 = &(obj.key1); 9 | let key2 = &(obj.key2); 10 | println!("Hello! {}, {}", key1, key2); 11 | } 12 | 13 | #[derive(Deserialize, Debug)] 14 | struct FaasInput { 15 | key1: String, 16 | key2: String 17 | } 18 | --------------------------------------------------------------------------------