diff options
| author | misskey-release-bot[bot] <157398866+misskey-release-bot[bot]@users.noreply.github.com> | 2025-12-06 12:22:58 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-06 12:22:58 +0000 |
| commit | e40c84f31df0202351c5585d3edbca000846b73b (patch) | |
| tree | 548eafb27b758c55de2e750a0ef9efbe3f056357 /packages/backend/scripts | |
| parent | Merge pull request #16840 from misskey-dev/develop (diff) | |
| parent | Release: 2025.12.0 (diff) | |
| download | misskey-e40c84f31df0202351c5585d3edbca000846b73b.tar.gz misskey-e40c84f31df0202351c5585d3edbca000846b73b.tar.bz2 misskey-e40c84f31df0202351c5585d3edbca000846b73b.zip | |
Merge pull request #16916 from misskey-dev/develop
Release: 2025.12.0
Diffstat (limited to 'packages/backend/scripts')
| -rw-r--r-- | packages/backend/scripts/compile_config.js | 54 | ||||
| -rw-r--r-- | packages/backend/scripts/dev.mjs | 2 | ||||
| -rw-r--r-- | packages/backend/scripts/measure-memory.mjs | 152 |
3 files changed, 207 insertions, 1 deletions
diff --git a/packages/backend/scripts/compile_config.js b/packages/backend/scripts/compile_config.js new file mode 100644 index 0000000000..e78fa3dc9f --- /dev/null +++ b/packages/backend/scripts/compile_config.js @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +/** + * YAMLファイルをJSONファイルに変換するスクリプト + * ビルド前に実行し、ランタイムにjs-yamlを含まないようにする + */ + +import fs from 'node:fs'; +import { resolve, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import yaml from 'js-yaml'; + +const _filename = fileURLToPath(import.meta.url); +const _dirname = dirname(_filename); + +const configDir = resolve(_dirname, '../../../.config'); +const OUTPUT_PATH = resolve(_dirname, '../../../built/.config.json'); + +// TODO: yamlのパースに失敗したときのエラーハンドリング + +/** + * YAMLファイルをJSONファイルに変換 + * @param {string} ymlPath - YAMLファイルのパス + */ +function yamlToJson(ymlPath) { + if (!fs.existsSync(ymlPath)) { + console.warn(`YAML file not found: ${ymlPath}`); + return; + } + + console.log(`${ymlPath} → ${OUTPUT_PATH}`); + + const yamlContent = fs.readFileSync(ymlPath, 'utf-8'); + const jsonContent = yaml.load(yamlContent); + if (!fs.existsSync(dirname(OUTPUT_PATH))) { + fs.mkdirSync(dirname(OUTPUT_PATH), { recursive: true }); + } + fs.writeFileSync(OUTPUT_PATH, JSON.stringify({ + '_NOTE_': 'This file is auto-generated from YAML file. DO NOT EDIT.', + ...jsonContent, + }), 'utf-8'); +} + +if (process.env.MISSKEY_CONFIG_YML) { + const customYmlPath = resolve(configDir, process.env.MISSKEY_CONFIG_YML); + yamlToJson(customYmlPath); +} else { + yamlToJson(resolve(configDir, process.env.NODE_ENV === 'test' ? 'test.yml' : 'default.yml')); +} + +console.log('Configuration compiled ✓'); diff --git a/packages/backend/scripts/dev.mjs b/packages/backend/scripts/dev.mjs index 023eb7eae6..db96eaf976 100644 --- a/packages/backend/scripts/dev.mjs +++ b/packages/backend/scripts/dev.mjs @@ -42,7 +42,7 @@ async function killProc() { './node_modules/nodemon/bin/nodemon.js', [ '-w', 'src', - '-e', 'ts,js,mjs,cjs,json,pug', + '-e', 'ts,js,mjs,cjs,tsx,json,pug', '--exec', 'pnpm', 'run', 'build', ], { diff --git a/packages/backend/scripts/measure-memory.mjs b/packages/backend/scripts/measure-memory.mjs new file mode 100644 index 0000000000..017252d7ec --- /dev/null +++ b/packages/backend/scripts/measure-memory.mjs @@ -0,0 +1,152 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +/** + * This script starts the Misskey backend server, waits for it to be ready, + * measures memory usage, and outputs the result as JSON. + * + * Usage: node scripts/measure-memory.mjs + */ + +import { fork } from 'node:child_process'; +import { setTimeout } from 'node:timers/promises'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const STARTUP_TIMEOUT = 120000; // 120 seconds timeout for server startup +const MEMORY_SETTLE_TIME = 10000; // Wait 10 seconds after startup for memory to settle + +async function measureMemory() { + const startTime = Date.now(); + + // Start the Misskey backend server using fork to enable IPC + const serverProcess = fork(join(__dirname, '../built/boot/entry.js'), [], { + cwd: join(__dirname, '..'), + env: { + ...process.env, + NODE_ENV: 'test', + }, + stdio: ['pipe', 'pipe', 'pipe', 'ipc'], + }); + + let serverReady = false; + + // Listen for the 'ok' message from the server indicating it's ready + serverProcess.on('message', (message) => { + if (message === 'ok') { + serverReady = true; + } + }); + + // Handle server output + serverProcess.stdout?.on('data', (data) => { + process.stderr.write(`[server stdout] ${data}`); + }); + + serverProcess.stderr?.on('data', (data) => { + process.stderr.write(`[server stderr] ${data}`); + }); + + // Handle server error + serverProcess.on('error', (err) => { + process.stderr.write(`[server error] ${err}\n`); + }); + + // Wait for server to be ready or timeout + const startupStartTime = Date.now(); + while (!serverReady) { + if (Date.now() - startupStartTime > STARTUP_TIMEOUT) { + serverProcess.kill('SIGTERM'); + throw new Error('Server startup timeout'); + } + await setTimeout(100); + } + + const startupTime = Date.now() - startupStartTime; + process.stderr.write(`Server started in ${startupTime}ms\n`); + + // Wait for memory to settle + await setTimeout(MEMORY_SETTLE_TIME); + + // Get memory usage from the server process via /proc + const pid = serverProcess.pid; + let memoryInfo; + + try { + const fs = await import('node:fs/promises'); + + // Read /proc/[pid]/status for detailed memory info + const status = await fs.readFile(`/proc/${pid}/status`, 'utf-8'); + const vmRssMatch = status.match(/VmRSS:\s+(\d+)\s+kB/); + const vmDataMatch = status.match(/VmData:\s+(\d+)\s+kB/); + const vmSizeMatch = status.match(/VmSize:\s+(\d+)\s+kB/); + + memoryInfo = { + rss: vmRssMatch ? parseInt(vmRssMatch[1], 10) * 1024 : null, + heapUsed: vmDataMatch ? parseInt(vmDataMatch[1], 10) * 1024 : null, + vmSize: vmSizeMatch ? parseInt(vmSizeMatch[1], 10) * 1024 : null, + }; + } catch (err) { + // Fallback: use ps command + process.stderr.write(`Warning: Could not read /proc/${pid}/status: ${err}\n`); + + const { execSync } = await import('node:child_process'); + try { + const ps = execSync(`ps -o rss= -p ${pid}`, { encoding: 'utf-8' }); + const rssKb = parseInt(ps.trim(), 10); + memoryInfo = { + rss: rssKb * 1024, + heapUsed: null, + vmSize: null, + }; + } catch { + memoryInfo = { + rss: null, + heapUsed: null, + vmSize: null, + error: 'Could not measure memory', + }; + } + } + + // Stop the server + serverProcess.kill('SIGTERM'); + + // Wait for process to exit + let exited = false; + await new Promise((resolve) => { + serverProcess.on('exit', () => { + exited = true; + resolve(undefined); + }); + // Force kill after 10 seconds if not exited + setTimeout(10000).then(() => { + if (!exited) { + serverProcess.kill('SIGKILL'); + } + resolve(undefined); + }); + }); + + const result = { + timestamp: new Date().toISOString(), + startupTimeMs: startupTime, + memory: memoryInfo, + }; + + // Output as JSON to stdout + console.log(JSON.stringify(result, null, 2)); +} + +measureMemory().catch((err) => { + console.error(JSON.stringify({ + error: err.message, + timestamp: new Date().toISOString(), + })); + process.exit(1); +}); |