1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-29 02:29:06 -05:00
denoland-deno/js/trace.ts

81 lines
2 KiB
TypeScript
Raw Normal View History

2018-09-22 03:59:26 -04:00
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
2018-10-03 21:18:23 -04:00
import * as msg from "gen/msg_generated";
2018-09-22 03:59:26 -04:00
export interface TraceInfo {
sync: boolean; // is synchronous call
name: string; // name of operation
}
interface TraceStackNode {
list: TraceInfo[];
prev: TraceStackNode | null;
}
let current: TraceStackNode | null = null;
// Push a new list to trace stack
function pushStack(): void {
if (current === null) {
current = { list: [], prev: null };
} else {
const newStack = { list: [], prev: current };
current = newStack;
}
}
// Pop from trace stack and (if possible) concat to parent trace stack node
function popStack(): TraceInfo[] {
if (current === null) {
throw new Error("trace list stack should not be empty");
}
const resultList = current!.list;
if (!!current!.prev) {
const prev = current!.prev!;
// concat inner results to outer stack
prev.list = prev.list.concat(resultList);
current = prev;
} else {
current = null;
}
return resultList;
}
// Push to trace stack if we are tracing
// @internal
2018-10-03 21:18:23 -04:00
export function maybePushTrace(op: msg.Any, sync: boolean): void {
2018-09-22 03:59:26 -04:00
if (current === null) {
return; // no trace requested
}
// Freeze the object, avoid tampering
current!.list.push(
Object.freeze({
sync,
2018-10-03 21:18:23 -04:00
name: msg.Any[op] // convert to enum names
2018-09-22 03:59:26 -04:00
})
);
}
2018-10-14 16:29:50 -04:00
/** Trace privileged operations executed inside a given function or promise.
*
* _Notice:_ To capture every operation in asynchronous `deno.*` calls,
2018-09-22 03:59:26 -04:00
* you might want to put them in functions instead of directly invoking.
*
2018-10-14 16:29:50 -04:00
* import { trace, mkdir } from "deno";
2018-09-22 03:59:26 -04:00
*
2018-10-14 16:29:50 -04:00
* const ops = await trace(async () => {
* await mkdir("my_dir");
* });
2018-09-22 03:59:26 -04:00
*/
export async function trace(
// tslint:disable-next-line:no-any
fnOrPromise: Function | Promise<any>
): Promise<TraceInfo[]> {
pushStack();
if (typeof fnOrPromise === "function") {
await fnOrPromise();
} else {
await fnOrPromise;
}
return popStack();
}