UNPKG

@clickup/pg-microsharding

Version:
208 lines 10.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.actionList = actionList; exports.calcIslandWeights = calcIslandWeights; const chalk_1 = __importDefault(require("chalk")); const chunk_1 = __importDefault(require("lodash/chunk")); const compact_1 = __importDefault(require("lodash/compact")); const first_1 = __importDefault(require("lodash/first")); const flatten_1 = __importDefault(require("lodash/flatten")); const mapValues_1 = __importDefault(require("lodash/mapValues")); const max_1 = __importDefault(require("lodash/max")); const range_1 = __importDefault(require("lodash/range")); const round_1 = __importDefault(require("lodash/round")); const sum_1 = __importDefault(require("lodash/sum")); const sumBy_1 = __importDefault(require("lodash/sumBy")); const table_1 = require("table"); const weights_1 = require("../api/weights"); const chunkIntoN_1 = require("../internal/chunkIntoN"); const getSchemaWeights_1 = require("../internal/getSchemaWeights"); const indent_1 = require("../internal/indent"); const logging_1 = require("../internal/logging"); const names_1 = require("../internal/names"); const normalizeDsns_1 = require("../internal/normalizeDsns"); const pluralize_1 = require("../internal/pluralize"); const promiseAllMap_1 = require("../internal/promiseAllMap"); const DEBUG_RENDER_MUL = parseInt((_a = process.env["DEBUG_RENDER_MUL"]) !== null && _a !== void 0 ? _a : "0") || 0; /** * Shows the list of microshards and their weights. */ async function actionList(args) { var _a, _b; const weightSql = args["weight-sql"] || undefined; const verbose = !!args["verbose"]; const json = !!args["json"]; const dsns = await (0, normalizeDsns_1.normalizeDsns)(args["dsns"] || args["dsn"]); if (dsns.length === 0) { throw "Please provide --dsn or --dsns, DB DSNs to list the microshards on"; } const { islandNosToDsn, islands } = await calcIslandWeights({ dsns, weightSql, verbose, }); if (DEBUG_RENDER_MUL > 0) { [...islands.values()].forEach((shards) => shards.push(...(0, flatten_1.default)((0, range_1.default)(DEBUG_RENDER_MUL - 1).map(() => shards)))); } const grandTotalWeightColName = (_a = (0, first_1.default)((0, flatten_1.default)([...islands.values()]).map((s) => s.weightColName))) !== null && _a !== void 0 ? _a : getSchemaWeights_1.WEIGHT_COL_NAME_DEFAULT; const grandTotalWeight = (0, round_1.default)((0, sum_1.default)((0, flatten_1.default)([...islands.values()]).map((s) => s.weight)), 2); const grandTotalUnit = (0, first_1.default)((0, compact_1.default)((0, flatten_1.default)([...islands.values()]).map((s) => s.unit))); const grandTotalShards = (0, sum_1.default)([...islands.values()].map((s) => s.length)); const firstShard = (0, first_1.default)((0, first_1.default)([...islands.values()].filter((s) => s.length > 0))); const header = ["Microshard"].concat(firstShard ? [ firstShard.weightColName, `${firstShard.weightColName} %`, ...Object.keys(firstShard.other), ] : [getSchemaWeights_1.WEIGHT_COL_NAME_DEFAULT, `${getSchemaWeights_1.WEIGHT_COL_NAME_DEFAULT} %`]); // Width in characters of the longest rendered table row. const tableWidth = 2 + // indent header.length * 3 + // left borders and paddings around each cell 1 + // last border ((_b = (0, max_1.default)( // content of the longest row (0, flatten_1.default)([...islands.values()]).map(({ weight, appliedFactor, unit, otherNormalized, no }) => // Microshard Math.max(header[0].length, no.toString().length) + // Weight or Size or ... Math.max(header[2].length, (0, round_1.default)(weight / appliedFactor, 5).toString().length + (unit ? unit.length + 1 : 0) + (appliedFactor !== 1 ? ` ✖${appliedFactor}`.length : 0)) + // Weight or Size or ... % Math.max(header[2].length, "100%".length) + // Other columns (0, sum_1.default)(Object.entries(otherNormalized).map(([k, v]) => Math.max(k.length, v.length)))))) !== null && _b !== void 0 ? _b : 0); const maxTablesSideBySide = Math.trunc(((logging_1.stdout.columns || 80) - 10) / tableWidth); const toPrint = { islands: [...islands].map(([islandNo, shards]) => { var _a, _b; const dsn = islandNosToDsn.get(islandNo); const totalWeight = (0, sumBy_1.default)(shards, (shard) => shard.weight); const totalUnit = (_a = (0, first_1.default)(shards)) === null || _a === void 0 ? void 0 : _a.unit; const totalOther = (0, mapValues_1.default)((_b = (0, first_1.default)(shards)) === null || _b === void 0 ? void 0 : _b.other, (_, k) => { const values = shards .map(({ other }) => parseFloat(other[k])) .filter((v) => !isNaN(v)); return values.length > 0 ? (0, sum_1.default)(values).toString() : undefined; }); return { no: islandNo, caption: `${(0, names_1.dsnShort)(dsn)} — ` + `${(0, pluralize_1.pluralize)(shards.length, "microshard")}`, dsn: (0, names_1.dsnShort)(dsn), header, shards: shards.map(({ no, weight, appliedFactor, unit, otherNormalized }) => [ no.toString(), (0, round_1.default)(weight / appliedFactor, 5).toString() + (unit ? ` ${unit}` : "") + (appliedFactor !== 1 ? ` ✖${appliedFactor}` : ""), totalWeight !== 0 ? `${((weight / totalWeight) * 100).toFixed(1)}%` : "-", ...Object.values(otherNormalized), ]), total: shards.length > 0 ? [ "total", totalWeight + (totalUnit ? ` ${totalUnit}` : ""), "100%", ...Object.values(totalOther).map((v) => v !== null && v !== void 0 ? v : ""), ] : undefined, }; }), total: `TOTAL ${grandTotalWeightColName.toUpperCase()}: ${grandTotalWeight}` + (grandTotalUnit ? ` ${grandTotalUnit}` : "") + `, ${(0, pluralize_1.pluralize)(islands.size, "island")}, ${(0, pluralize_1.pluralize)(grandTotalShards, "microshard")}`, }; if (json) { (0, logging_1.print)(JSON.stringify(toPrint, null, 2) + "\n"); return true; } for (const island of toPrint.islands) { logging_1.print.section(island.caption); if (island.shards.length === 0) { (0, logging_1.print)((0, indent_1.indent)((0, table_1.table)([["No microshards"]]))); continue; } const tables = json || islands.size === 1 || maxTablesSideBySide === 0 || grandTotalShards + islands.size * 8 < (logging_1.stdout.rows || 25) || island.shards.length <= 4 ? [island.shards] : island.shards.length / maxTablesSideBySide < 2 ? (0, chunk_1.default)(island.shards, 2) : (0, chunkIntoN_1.chunkIntoN)(island.shards, maxTablesSideBySide); (0, logging_1.print)(glueHorizontally(tables.map((tbl, tblNo) => (0, indent_1.indent)((0, table_1.table)((0, compact_1.default)([ island.header.map((cell) => chalk_1.default.bold(cell)), ...tbl.map((row) => row[0].trim() === "0" ? row.map((cell) => chalk_1.default.yellow(cell)) : row), tblNo === 0 && island.total && island.total.map((cell) => chalk_1.default.bold(cell)), ]), { drawHorizontalLine: (i, rowCount) => i === 0 || i === 1 || (tblNo === 0 && i === rowCount - 1) || i === rowCount, }))))); } (0, logging_1.print)(chalk_1.default.bgBlue(" " + chalk_1.default.whiteBright(toPrint.total) + " ") + (verbose && !weightSql ? "" : " (try --verbose)")); return true; } async function calcIslandWeights({ dsns, weightSql, verbose, }) { try { const pendingPrefix = "Calculating microshard sizes on: "; const pendingDsns = new Set(); const islandNosToDsn = new Map([...dsns.entries()]); const islands = new Map(await (0, promiseAllMap_1.promiseAllMap)([...islandNosToDsn.entries()], async ([islandNo, dsn]) => { try { pendingDsns.add((0, names_1.dsnShort)(dsn)); (0, logging_1.progress)(pendingPrefix + [...pendingDsns].join(", ")); const shards = await (0, weights_1.weights)({ dsn, weightSql, verbose, }); return [islandNo, shards]; } finally { pendingDsns.delete((0, names_1.dsnShort)(dsn)); if (pendingDsns.size > 0) { (0, logging_1.progress)(pendingPrefix + [...pendingDsns].join(", ")); } } })); return { islandNosToDsn, islands }; } finally { logging_1.progress.clear(); } } function glueHorizontally(tables) { var _a; const rowsByTable = tables.map((table) => table.split("\n")); const maxRows = (_a = (0, max_1.default)(rowsByTable.map((rows) => rows.length))) !== null && _a !== void 0 ? _a : 0; for (const rows of rowsByTable) { const maxWidth = rows[0].length; for (let i = 0; i < maxRows; i++) { rows[i] || (rows[i] = ""); rows[i] = rows[i].padEnd(maxWidth, " "); } } const result = (0, range_1.default)(maxRows).map(() => []); for (const rows of rowsByTable) { for (const [i, col] of rows.entries()) { result[i].push(col); } } return result.map((lineArray) => lineArray.join("")).join("\n"); } //# sourceMappingURL=actionList.js.map