Skip to content

Commit

Permalink
feat: upgrade assemblyscript faas demo(#256) (#486)
Browse files Browse the repository at this point in the history
  • Loading branch information
nanjingboy authored Apr 22, 2022
1 parent 8d89e8e commit 78a4d88
Show file tree
Hide file tree
Showing 10 changed files with 264 additions and 95 deletions.
8 changes: 8 additions & 0 deletions demo/faas/code/assemblyscript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Build

The Node.js version should >=16.14.0.

* npm i
* npm run asbuild
* Copy build/function_1.wasm and build/function_2.wasm to your actual directory.
* Test the demo follow https://mosn.io/layotto/#/zh/start/faas/start.
23 changes: 13 additions & 10 deletions demo/faas/code/assemblyscript/asconfig.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
{
"targets": {
"debug": {
"binaryFile": "build/untouched.wasm",
"textFile": "build/untouched.wat",
"sourceMap": true,
"debug": true
"client": {
"outFile": "build/function_1.wasm",
"sourceMap": false,
"optimizeLevel": 3,
"shrinkLevel": 0,
"converge": false,
"noAssert": false
},
"release": {
"binaryFile": "build/optimized.wasm",
"textFile": "build/optimized.wat",
"sourceMap": true,
"server": {
"outFile": "build/function_2.wasm",
"sourceMap": false,
"optimizeLevel": 3,
"shrinkLevel": 0,
"converge": false,
"noAssert": false
}
},
"options": {}
"options": {
"bindings": "esm"
}
}
59 changes: 59 additions & 0 deletions demo/faas/code/assemblyscript/assembly/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {
BufferTypeValues,
Context,
FilterDataStatusValues,
get_buffer_bytes,
log,
LogLevelValues,
registerRootContext,
RootContext,
set_http_response_body,
} from "@nobodyiam/proxy-runtime/assembly";
import { invokeService, registerId } from "./proxy";

export * from "@nobodyiam/proxy-runtime/assembly/proxy";

function getBookName(body: string): string | null {
const parts = body.split("&");
for (let index = 0; index < parts.length; ++index) {
const item = parts[index];
if (item.startsWith("name=")) {
return item.slice("name=".length);
}
}
return null;
}

class ClientRootHttpContext extends RootContext {
createContext(context_id: u32): Context {
return new ClientHttpContext(context_id, this);
}
}

class ClientHttpContext extends Context {
constructor(context_id: u32, root_context: ClientRootHttpContext) {
super(context_id, root_context);
}

onRequestBody(body_buffer_length: usize, _end_of_stream: bool): FilterDataStatusValues {
const name = getBookName(
String.UTF8.decode(get_buffer_bytes(BufferTypeValues.HttpRequestBody, 0, body_buffer_length as u32))
);
if (name === null) {
log(LogLevelValues.error, "Param 'name' not found");
} else {
set_http_response_body(`There are ${String.UTF8.decode(invokeService("id_2", "", name))} inventories for ${name}.\n`);
}
return FilterDataStatusValues.Continue
}
}

export function _start(): void {
registerRootContext((context_id: u32) => {
return new ClientRootHttpContext(context_id);
}, "");
}

export function proxy_get_id(): void {
registerId("id_1");
}
37 changes: 0 additions & 37 deletions demo/faas/code/assemblyscript/assembly/index.ts

This file was deleted.

98 changes: 98 additions & 0 deletions demo/faas/code/assemblyscript/assembly/proxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import * as imports from '@nobodyiam/proxy-runtime/assembly/imports';
import { free } from '@nobodyiam/proxy-runtime/assembly/malloc';
import { WasmResultValues, BufferTypeValues, LogLevelValues, log } from "@nobodyiam/proxy-runtime/assembly";

class ArrayBufferReference {
private buffer: usize;
private size: usize;
constructor() {
}
sizePtr(): usize {
return changetype<usize>(this) + offsetof<ArrayBufferReference>("size");
}
bufferPtr(): usize {
return changetype<usize>(this) + offsetof<ArrayBufferReference>("buffer");
}
// Before calling toArrayBuffer below, you must call out to the host to fill in the values.
// toArrayBuffer below **must** be called once and only once.
toArrayBuffer(): ArrayBuffer {
if (this.size == 0) {
return new ArrayBuffer(0);
}
let array = changetype<ArrayBuffer>(this.buffer);
// host code used malloc to allocate this buffer.
// release the allocated ptr. array variable will retain it, so it won't be actually free (as it is ref counted).
free(this.buffer);
// should we return a this sliced up to size?
return array;
}
}
var globalArrayBufferReference = new ArrayBufferReference();
type ptr<T> = usize;

export function registerId(id: string): WasmResultValues {
const idBuffer = String.UTF8.encode(id);
const result = imports.proxy_set_buffer_bytes(BufferTypeValues.CallData, 0, id.length,
changetype<usize>(idBuffer), idBuffer.byteLength);
if (result != WasmResultValues.Ok) {
// @ts-ignore
log(LogLevelValues.critical, `Unable to set http response body: ${id} with result: ${result}`);
}
return result;
}

// @ts-ignore: decorator
@external("env", "proxy_invoke_service")
declare function proxy_invoke_service(
idPtr: ptr<u8>,
idSize: usize,
methodPtr: ptr<u8>,
messageSize: ptr<usize>,
paramPtr: ptr<u8>,
paramSize: usize,
resultPtr: ptr<ptr<u8>>,
resultSize: ptr<usize>,
): u32;

export function invokeService(id: string, method: string, param: string): ArrayBuffer {
const idBuffer = String.UTF8.encode(id);
const methodBuffer = String.UTF8.encode(method);
const paramBuffer = String.UTF8.encode(param);
let result = proxy_invoke_service(
changetype<usize>(idBuffer), idBuffer.byteLength,
changetype<usize>(methodBuffer), methodBuffer.byteLength,
changetype<usize>(paramBuffer), paramBuffer.byteLength,
globalArrayBufferReference.bufferPtr(),
globalArrayBufferReference.sizePtr(),
);
if (result == WasmResultValues.Ok) {
return globalArrayBufferReference.toArrayBuffer();
}
return new ArrayBuffer(0);
}

// @ts-ignore: decorator
@external("env", "proxy_get_state")
declare function proxy_get_state(
storeNamePtr: ptr<u8>,
storeNameSize: usize,
keyPtr: ptr<u8>,
keySize: ptr<usize>,
resultPtr: ptr<ptr<u8>>,
resultSize: ptr<usize>,
): u32;

export function getState(storeName: string, key: string): ArrayBuffer {
const storeNameBuffer = String.UTF8.encode(storeName);
const keyBuffer = String.UTF8.encode(key);
let result = proxy_get_state(
changetype<usize>(storeNameBuffer), storeNameBuffer.byteLength,
changetype<usize>(keyBuffer), keyBuffer.byteLength,
globalArrayBufferReference.bufferPtr(),
globalArrayBufferReference.sizePtr(),
);
if (result == WasmResultValues.Ok) {
return globalArrayBufferReference.toArrayBuffer();
}
return new ArrayBuffer(0);
}
40 changes: 40 additions & 0 deletions demo/faas/code/assemblyscript/assembly/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
BufferTypeValues,
Context,
FilterDataStatusValues,
get_buffer_bytes,
registerRootContext,
RootContext,
set_http_response_body,
} from "@nobodyiam/proxy-runtime/assembly";
import { getState, registerId } from "./proxy";

export * from "@nobodyiam/proxy-runtime/assembly/proxy";

class ServerRootHttpContext extends RootContext {
createContext(context_id: u32): Context {
return new ServerHttpContext(context_id, this);
}
}

class ServerHttpContext extends Context {
constructor(context_id: u32, root_context: ServerRootHttpContext) {
super(context_id, root_context);
}

onRequestBody(body_buffer_length: usize, _end_of_stream: bool): FilterDataStatusValues {
let name = String.UTF8.decode(get_buffer_bytes(BufferTypeValues.HttpRequestBody, 0, body_buffer_length as u32));
set_http_response_body(String.UTF8.decode(getState("redis", name)));
return FilterDataStatusValues.Continue
}
}

export function _start(): void {
registerRootContext((context_id: u32) => {
return new ServerRootHttpContext(context_id);
}, "");
}

export function proxy_get_id(): void {
registerId("id_2");
}
2 changes: 2 additions & 0 deletions demo/faas/code/assemblyscript/build/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
5 changes: 0 additions & 5 deletions demo/faas/code/assemblyscript/index.js

This file was deleted.

Loading

0 comments on commit 78a4d88

Please sign in to comment.