From 9398ff6874389d9b0e4a076835bb8ed364e1f518 Mon Sep 17 00:00:00 2001 From: Jordan Last Date: Fri, 26 Jan 2024 12:26:25 -0600 Subject: [PATCH] moving event loop into one function, various cleanups --- contributing/wasmedge_quickjs.md | 7 +++ package-lock.json | 12 +---- package.json | 3 +- src/compiler/rust/canister/src/ic/call_raw.rs | 17 ++----- .../rust/canister/src/ic/call_raw128.rs | 17 ++----- .../rust/canister/src/ic/set_timer.rs | 15 +----- .../canister/src/ic/set_timer_interval.rs | 15 +----- src/compiler/rust/canister/src/lib.rs | 51 ++++++------------- src/compiler/rust/canister_methods/src/lib.rs | 42 ++++----------- src/compiler/utils/global_paths.ts | 11 ++-- src/lib/globals.ts | 3 -- src/lib/server.ts | 10 ++-- 12 files changed, 51 insertions(+), 152 deletions(-) create mode 100644 contributing/wasmedge_quickjs.md diff --git a/contributing/wasmedge_quickjs.md b/contributing/wasmedge_quickjs.md new file mode 100644 index 0000000000..e2b979627a --- /dev/null +++ b/contributing/wasmedge_quickjs.md @@ -0,0 +1,7 @@ +To develop locally you will need to do the following: + +1. Set the `AZLE_WASMEDGE_QUICKJS_DIR` environment variable on deploy or test to the location of your locally cloned `wasmedge-quickjs`. + +2. Change the `wasmedge_quickjs` dependency in `azle/rust/canister/Cargo.toml` to the location of your locally cloned `wasmedge-quickjs`. + +3. When you are ready to commit your changes, make sure to update `azle/install_rust_dependencies.sh` with the new git commit hash of the `wasmedge-quickjs` repository, and delete the `wasmedge-quickjs` directory in `~/.config/azle/[version]`. diff --git a/package-lock.json b/package-lock.json index bb73ac381e..3087081bc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,8 +22,7 @@ "text-encoding": "0.7.0", "ts-node": "10.3.1", "typescript": "^5.2.2", - "uuid": "^9.0.1", - "zlib": "^1.0.5" + "uuid": "^9.0.1" }, "bin": { "azle": "bin.js" @@ -3978,15 +3977,6 @@ "engines": { "node": ">=6" } - }, - "node_modules/zlib": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zlib/-/zlib-1.0.5.tgz", - "integrity": "sha512-40fpE2II+Cd3k8HWTWONfeKE2jL+P42iWJ1zzps5W51qcTsOUKM5Q5m2PFb0CLxlmFAaUuUdJGc3OfZy947v0w==", - "hasInstallScript": true, - "engines": { - "node": ">=0.2.0" - } } } } diff --git a/package.json b/package.json index 81ff60a929..d88b7ab186 100644 --- a/package.json +++ b/package.json @@ -38,8 +38,7 @@ "text-encoding": "0.7.0", "ts-node": "10.3.1", "typescript": "^5.2.2", - "uuid": "^9.0.1", - "zlib": "^1.0.5" + "uuid": "^9.0.1" }, "devDependencies": { "@dfinity/agent": "^0.19.2", diff --git a/src/compiler/rust/canister/src/ic/call_raw.rs b/src/compiler/rust/canister/src/ic/call_raw.rs index 9d6b8a9899..0201dc4817 100644 --- a/src/compiler/rust/canister/src/ic/call_raw.rs +++ b/src/compiler/rust/canister/src/ic/call_raw.rs @@ -2,7 +2,7 @@ use wasmedge_quickjs::{AsObject, Context, JsFn, JsValue}; -use crate::RUNTIME; +use crate::{run_event_loop, RUNTIME}; pub struct NativeFunction; impl JsFn for NativeFunction { @@ -91,7 +91,7 @@ impl JsFn for NativeFunction { js_exception.dump_error(); panic!("TODO needs error info"); } - _ => {} + _ => run_event_loop(context), }; } else { let reject = global @@ -113,20 +113,9 @@ impl JsFn for NativeFunction { js_exception.dump_error(); panic!("TODO needs error info"); } - _ => {} + _ => run_event_loop(context), }; } - - context.promise_loop_poll(); - - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; - } - } }); }); }); diff --git a/src/compiler/rust/canister/src/ic/call_raw128.rs b/src/compiler/rust/canister/src/ic/call_raw128.rs index dffcc70aa3..bd36a7709d 100644 --- a/src/compiler/rust/canister/src/ic/call_raw128.rs +++ b/src/compiler/rust/canister/src/ic/call_raw128.rs @@ -2,7 +2,7 @@ use wasmedge_quickjs::{AsObject, Context, JsFn, JsValue}; -use crate::RUNTIME; +use crate::{run_event_loop, RUNTIME}; pub struct NativeFunction; impl JsFn for NativeFunction { @@ -91,7 +91,7 @@ impl JsFn for NativeFunction { js_exception.dump_error(); panic!("TODO needs error info"); } - _ => {} + _ => run_event_loop(context), }; } else { let reject = global @@ -113,20 +113,9 @@ impl JsFn for NativeFunction { js_exception.dump_error(); panic!("TODO needs error info"); } - _ => {} + _ => run_event_loop(context), }; } - - context.promise_loop_poll(); - - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; - } - } }); }); }); diff --git a/src/compiler/rust/canister/src/ic/set_timer.rs b/src/compiler/rust/canister/src/ic/set_timer.rs index 1b17abd037..d20bfcf9e7 100644 --- a/src/compiler/rust/canister/src/ic/set_timer.rs +++ b/src/compiler/rust/canister/src/ic/set_timer.rs @@ -1,7 +1,7 @@ use slotmap::Key; use wasmedge_quickjs::{AsObject, Context, JsFn, JsValue}; -use crate::RUNTIME; +use crate::{run_event_loop, RUNTIME}; pub struct NativeFunction; impl JsFn for NativeFunction { @@ -47,20 +47,9 @@ impl JsFn for NativeFunction { js_exception.dump_error(); panic!("TODO needs error info"); } - _ => {} + _ => run_event_loop(context), }; - context.promise_loop_poll(); - - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; - } - } - // TODO handle errors }); }); diff --git a/src/compiler/rust/canister/src/ic/set_timer_interval.rs b/src/compiler/rust/canister/src/ic/set_timer_interval.rs index 6e14a56b7a..3894e04306 100644 --- a/src/compiler/rust/canister/src/ic/set_timer_interval.rs +++ b/src/compiler/rust/canister/src/ic/set_timer_interval.rs @@ -1,7 +1,7 @@ use slotmap::Key; use wasmedge_quickjs::{AsObject, Context, JsFn, JsValue}; -use crate::RUNTIME; +use crate::{run_event_loop, RUNTIME}; pub struct NativeFunction; impl JsFn for NativeFunction { @@ -47,20 +47,9 @@ impl JsFn for NativeFunction { js_exception.dump_error(); panic!("TODO needs error info"); } - _ => {} + _ => run_event_loop(context), }; - context.promise_loop_poll(); - - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; - } - } - // TODO handle errors }); }); diff --git a/src/compiler/rust/canister/src/lib.rs b/src/compiler/rust/canister/src/lib.rs index d7e1ffc663..d6b27f65e6 100644 --- a/src/compiler/rust/canister/src/lib.rs +++ b/src/compiler/rust/canister/src/lib.rs @@ -108,19 +108,8 @@ fn execute_js(function_name: &str, pass_arg_data: bool) { js_exception.dump_error(); panic!("TODO needs error info"); } - _ => {} + _ => run_event_loop(context), }; - - context.promise_loop_poll(); - - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; - } - } }); }); } @@ -146,16 +135,7 @@ pub fn get_candid_pointer() -> *mut std::os::raw::c_char { "azle_main", ); - context.promise_loop_poll(); - - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; - } - } + run_event_loop(context); let global = context.get_global(); @@ -172,21 +152,9 @@ pub fn get_candid_pointer() -> *mut std::os::raw::c_char { js_exception.dump_error(); panic!("TODO needs error info"); } - _ => {} + _ => run_event_loop(context), }; - context.promise_loop_poll(); - - // TODO did I put this in the right place? - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; - } - } - let candid_info_string = candid_info.to_string().unwrap().to_string(); let c_string = std::ffi::CString::new(candid_info_string).unwrap(); @@ -195,3 +163,16 @@ pub fn get_candid_pointer() -> *mut std::os::raw::c_char { }) }) } + +fn run_event_loop(context: &mut wasmedge_quickjs::Context) { + context.promise_loop_poll(); + + while (true) { + let num_tasks = context.event_loop().unwrap().run_tick_task(); + context.promise_loop_poll(); + + if num_tasks == 0 { + break; + } + } +} diff --git a/src/compiler/rust/canister_methods/src/lib.rs b/src/compiler/rust/canister_methods/src/lib.rs index 917b9ed550..654dbd2fd2 100644 --- a/src/compiler/rust/canister_methods/src/lib.rs +++ b/src/compiler/rust/canister_methods/src/lib.rs @@ -72,16 +72,7 @@ pub fn canister_methods(_: TokenStream) -> TokenStream { context.eval_global_str("globalThis.exports = {};".to_string()); context.eval_module_str(std::str::from_utf8(MAIN_JS).unwrap().to_string(), "azle_main"); - context.promise_loop_poll(); - - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; - } - } + run_event_loop(context); // let temp = context.eval_module_str(std::str::from_utf8(MAIN_JS).unwrap().to_string(), "azle_main"); @@ -129,16 +120,7 @@ pub fn canister_methods(_: TokenStream) -> TokenStream { context.eval_global_str("globalThis.exports = {};".to_string()); context.eval_module_str(std::str::from_utf8(MAIN_JS).unwrap().to_string(), "azle_main"); - context.promise_loop_poll(); - - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; - } - } + run_event_loop(context); // let temp = context.eval_module_str(std::str::from_utf8(MAIN_JS).unwrap().to_string(), "azle_main"); @@ -320,26 +302,20 @@ fn get_guard_token_stream( // TODO we would really like wasmedge-quickjs to add // TODO good error info to JsException and move error handling // TODO out of our own code - let final_result = match &result { + match &result { wasmedge_quickjs::JsValue::Exception(js_exception) => { js_exception.dump_error(); Err("TODO needs error info".to_string()) } - _ => Ok(()) - }; - - context.promise_loop_poll(); + _ => { + // TODO what if errors happen in here? + // TODO can guard functions even be async? + // TODO I don't think they can + run_event_loop(context); - while (true) { - let num_tasks = context.event_loop().unwrap().run_tick_task(); - context.promise_loop_poll(); - - if num_tasks == 0 { - break; + Ok(()) } } - - final_result }) }) } diff --git a/src/compiler/utils/global_paths.ts b/src/compiler/utils/global_paths.ts index 7bd8eaa88e..2e219a29a1 100644 --- a/src/compiler/utils/global_paths.ts +++ b/src/compiler/utils/global_paths.ts @@ -27,11 +27,6 @@ export const GLOBAL_AZLE_BIN_DIR = join( 'bin' ); -export const GLOBAL_AZLE_WASMEDGE_QUICKJS_DIR = join( - GLOBAL_AZLE_CONFIG_DIR, - azleVersion, - 'wasmedge-quickjs' -); - -// This is for local development of wasmedge-quickjs js modules -// export const GLOBAL_AZLE_WASMEDGE_QUICKJS_DIR = '/home/wasmedge-quickjs'; +export const GLOBAL_AZLE_WASMEDGE_QUICKJS_DIR = + process.env.AZLE_WASMEDGE_QUICKJS_DIR ?? + join(GLOBAL_AZLE_CONFIG_DIR, azleVersion, 'wasmedge-quickjs'); diff --git a/src/lib/globals.ts b/src/lib/globals.ts index a6defc7e0d..780039321e 100644 --- a/src/lib/globals.ts +++ b/src/lib/globals.ts @@ -3,7 +3,6 @@ import { AzleIc } from './ic/types/azle_ic'; import { Buffer } from 'buffer'; import { replacer } from './stable_structures/stable_json'; import * as process from 'process'; -import { HttpResponse } from './server'; declare global { var _azleInsideCanister: boolean; @@ -14,8 +13,6 @@ declare global { var _azleIcTimers: { [key: string]: string }; var _azleTimerCallbacks: { [key: string]: () => void }; var _azleGuardFunctions: { [key: string]: () => any }; - var _azleExportedIc: typeof ic; - var _azleHttpResponse: typeof HttpResponse; } globalThis._azleInsideCanister = diff --git a/src/lib/server.ts b/src/lib/server.ts index 4641acb153..ae32f94a75 100644 --- a/src/lib/server.ts +++ b/src/lib/server.ts @@ -68,9 +68,6 @@ export const HttpRequest = Record({ certificate_version: Opt(nat16) }); -globalThis._azleHttpResponse = HttpResponse; -globalThis._azleExportedIc = ic; - let server: NodeServer; // TODO can the serverInit be async? @@ -164,7 +161,6 @@ export async function httpHandler( } if (typeof data === 'string') { - console.log('string'); this.responseData = Buffer.concat([ this.responseData, Buffer.from(data) @@ -173,11 +169,13 @@ export async function httpHandler( return; } - // TODO object is not done, it is not doing anything + // TODO I am not sure if this works + // TODO I did what I remember Rust doing + // TODO which is to just turn the object into a string if (typeof data === 'object') { this.responseData = Buffer.concat([ this.responseData, - Buffer.from([]) + Buffer.from(data.toString()) ]); return; }