Fix logging interface in avm client (#115)

This commit is contained in:
Pavel 2021-06-04 17:46:06 +03:00 committed by GitHub
parent 49f3afda4a
commit 7e34cac378
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 26 deletions

View File

@ -4,16 +4,7 @@ const vmPeerId = '12D3KooWNzutuy8WHXDKFqFsATvCR6j9cj2FijYbnd47geRKaQZS';
const createTestIntepreter = async (handler: ParticleHandler) => { const createTestIntepreter = async (handler: ParticleHandler) => {
return AirInterpreter.create(handler, vmPeerId, 'trace', (level, message) => { return AirInterpreter.create(handler, vmPeerId, 'trace', (level, message) => {
switch (level) { console.log(`level: ${level}, message=${message}`);
case 0:
case 1:
case 2:
console.log(message);
case 3:
console.warn(message);
case 4:
console.error(message);
}
}); });
}; };

View File

@ -18,7 +18,9 @@ import { toByteArray } from 'base64-js';
import { return_current_peer_id, return_call_service_result, getStringFromWasm0, free, invoke, ast } from './wrapper'; import { return_current_peer_id, return_call_service_result, getStringFromWasm0, free, invoke, ast } from './wrapper';
import wasmBs64 from './wasm'; import wasmBs64 from './wasm';
type LogLevel = 'info' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'off'; export type LogLevel = 'info' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'off';
export type LogFunction = (level: LogLevel, message: string) => void;
export interface CallServiceResult { export interface CallServiceResult {
ret_code: number; ret_code: number;
@ -78,10 +80,7 @@ class HostImportsConfig {
const interpreter_wasm = toByteArray(wasmBs64); const interpreter_wasm = toByteArray(wasmBs64);
/// Instantiates WebAssembly runtime with AIR interpreter module /// Instantiates WebAssembly runtime with AIR interpreter module
async function interpreterInstance( async function interpreterInstance(cfg: HostImportsConfig, logFunction: LogFunction): Promise<Instance> {
cfg: HostImportsConfig,
logWasm: (level: number, message: string) => void,
): Promise<Instance> {
/// Create host imports that use module exports internally /// Create host imports that use module exports internally
let imports = cfg.newImportObject(); let imports = cfg.newImportObject();
@ -93,28 +92,49 @@ async function interpreterInstance(
cfg.setExports(instance.exports); cfg.setExports(instance.exports);
/// Trigger interpreter initialization (i.e., call main function) /// Trigger interpreter initialization (i.e., call main function)
call_export(instance.exports.main, logWasm); call_export(instance.exports.main, logFunction);
return instance; return instance;
} }
/// If export is a function, call it. Otherwise log a warning. /// If export is a function, call it. Otherwise log a warning.
/// NOTE: any here is unavoidable, see Function interface definition /// NOTE: any here is unavoidable, see Function interface definition
function call_export(f: ExportValue, logWasm: (level: number, message: string) => void): any { function call_export(f: ExportValue, logFunction: LogFunction): any {
if (typeof f === 'function') { if (typeof f === 'function') {
return f(); return f();
} else { } else {
logWasm(3, `can't call export ${f}: it is not a function, but ${typeof f}`); logFunction('error', `can't call export ${f}: it is not a function, but ${typeof f}`);
} }
} }
function log_import(cfg: HostImportsConfig, logWasm: (level: number, message: string) => void): LogImport { function log_import(cfg: HostImportsConfig, logFunction: LogFunction): LogImport {
return { return {
log_utf8_string: (level: any, target: any, offset: any, size: any) => { log_utf8_string: (level: any, target: any, offset: any, size: any) => {
let wasm = cfg.exports; let wasm = cfg.exports;
try { try {
let str = getStringFromWasm0(wasm, offset, size); let str = getStringFromWasm0(wasm, offset, size);
logWasm(level, str); let levelStr: LogLevel;
switch (level) {
case 1:
levelStr = 'error';
break;
case 2:
levelStr = 'warn';
break;
case 3:
levelStr = 'info';
break;
case 4:
levelStr = 'debug';
break;
case 6:
levelStr = 'trace';
break;
default:
return;
}
logFunction(levelStr, str);
} finally { } finally {
} }
}, },
@ -126,7 +146,7 @@ function newImportObject(
particleHandler: ParticleHandler, particleHandler: ParticleHandler,
cfg: HostImportsConfig, cfg: HostImportsConfig,
peerId: string, peerId: string,
logWasm: (level: number, message: string) => void, logFunction: LogFunction,
): ImportObject { ): ImportObject {
return { return {
// __wbg_callserviceimpl_c0ca292e3c8c0c97 this is a function generated by bindgen. Could be changed. // __wbg_callserviceimpl_c0ca292e3c8c0c97 this is a function generated by bindgen. Could be changed.
@ -152,7 +172,7 @@ function newImportObject(
tetrapletsObject = JSON.parse(tetraplets); tetrapletsObject = JSON.parse(tetraplets);
serviceResult = particleHandler(serviceId, fnName, argsObject, tetrapletsObject); serviceResult = particleHandler(serviceId, fnName, argsObject, tetrapletsObject);
} catch (err) { } catch (err) {
logWasm(4, 'Cannot parse arguments: ' + JSON.stringify(err)); logFunction('error', 'Cannot parse arguments: ' + JSON.stringify(err));
serviceResult = { serviceResult = {
result: JSON.stringify('Cannot parse arguments: ' + JSON.stringify(err)), result: JSON.stringify('Cannot parse arguments: ' + JSON.stringify(err)),
ret_code: 1, ret_code: 1,
@ -170,7 +190,7 @@ function newImportObject(
throw new Error(`wbindgen throws: ${JSON.stringify(arg)}`); throw new Error(`wbindgen throws: ${JSON.stringify(arg)}`);
}, },
}, },
host: log_import(cfg, logWasm), host: log_import(cfg, logFunction),
}; };
} }
@ -186,13 +206,13 @@ export class AirInterpreter {
particleHandler: ParticleHandler, particleHandler: ParticleHandler,
peerId: string, peerId: string,
logLevel: LogLevel, logLevel: LogLevel,
logWasm: (level: number, message: string) => void, logFunction: LogFunction,
) { ) {
const cfg = new HostImportsConfig((cfg) => { const cfg = new HostImportsConfig((cfg) => {
return newImportObject(particleHandler, cfg, peerId, logWasm); return newImportObject(particleHandler, cfg, peerId, logFunction);
}); });
const instance = await interpreterInstance(cfg, logWasm); const instance = await interpreterInstance(cfg, logFunction);
const res = new AirInterpreter(instance); const res = new AirInterpreter(instance);
res.logLevel = logLevel; res.logLevel = logLevel;
return res; return res;