Path: blob/master/src/packages/database/conat/leak-search.ts
1503 views
/*1Code for testing for memory leaks. As of this commit, nothing tested for here2leaks memory in my dev setup.34USAGE:56Run with an account_id from your dev server and pass the expose-gc flag so the7gc command is defined:8910ACCOUNT_ID="6aae57c6-08f1-4bb5-848b-3ceb53e61ede" DEBUG=cocalc:* DEBUG_CONSOLE=yes node --expose-gc1112Then do this1314a = require('@cocalc/database/conat/leak-search')15await a.testQueryOnly(50)16await a.testChangefeed(50)1718Do a test multiple times to see if there is a real leak, e.g., the following is GOOD:1920> a.testChangefeed(50)21Promise {22<pending>,23[Symbol(async_id_symbol)]: 47,24[Symbol(trigger_async_id_symbol)]: 625}26> leaked 5.209536 MB2728> a.testChangefeed(50)29Promise {30<pending>,31[Symbol(async_id_symbol)]: 3167,32[Symbol(trigger_async_id_symbol)]: 633}34> leaked -0.029184 MB <--- GOOD!35*/3637import { db } from "@cocalc/database";38import { uuid } from "@cocalc/util/misc";39import { delay } from "awaiting";40import { callback2 } from "@cocalc/util/async-utils";4142// set env variable to an account_id on your dev server with lots of projects.43const ACCOUNT_ID = process.env.ACCOUNT_ID;4445export function create({ id, cb }: { id; cb? }) {46const d = db();47d.user_query({48query: {49projects_all: [50{ project_id: null, title: null, state: null, status: null },51],52},53changes: id,54account_id: ACCOUNT_ID,55cb: (err) => {56cb?.(err);57cb = undefined;58},59});60}6162export function cancel(id) {63db().user_query_cancel_changefeed({ id });64}6566let pre: any = { heapUsed: 0 };67async function before() {68gc?.();69await delay(500);70gc?.();71pre = process.memoryUsage();72}7374async function after() {75gc?.();76await delay(500);77gc?.();78const post = process.memoryUsage();79const leak = (post.heapUsed - pre.heapUsed) / 10 ** 6;80console.log("leaked", leak, "MB");81return leak;82}8384// This leaks horribly85export async function testChangefeed(n) {86await before();87for (let i = 0; i < n; i++) {88const id = uuid();89await callback2(create, { id });90cancel(id);91}92return await after();93}9495// query only does NOT leak96export async function testQueryOnly(n) {97await before();98for (let i = 0; i < n; i++) {99const d = db();100await callback2(d.user_query, {101query: {102projects_all: [103{ project_id: null, title: null, state: null, status: null },104],105},106account_id: "6aae57c6-08f1-4bb5-848b-3ceb53e61ede",107});108}109return await after();110}111112113