Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
51bb3a8967 | |||
c4a082031e | |||
761f9ca1b6 | |||
ad2c180cfe | |||
36eb1a79a7 | |||
8a0a9dedb1 |
22
changelog.md
22
changelog.md
@ -1,5 +1,27 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-03-01 - 1.3.0 - feat(cli)
|
||||||
|
Add CLI support with command parsing and version display
|
||||||
|
|
||||||
|
- Added a basic CLI interface using smartcli.
|
||||||
|
- Implemented command parsing with a 'restart' command.
|
||||||
|
- Integrated project version display in the CLI.
|
||||||
|
|
||||||
|
## 2025-03-01 - 1.2.0 - feat(core)
|
||||||
|
Introduce ProcessMonitor with memory management and spawning features
|
||||||
|
|
||||||
|
- Added ProcessMonitor class with functionality to manage process execution and memory usage.
|
||||||
|
- Implemented process spawning with ability to handle command arguments and directories.
|
||||||
|
- Added periodic memory monitoring and automatic restarts when memory thresholds are exceeded.
|
||||||
|
- ProcessMonitor now logs its actions with optional configuration name for better identification.
|
||||||
|
- Updated test file to include example usage of ProcessMonitor.
|
||||||
|
|
||||||
|
## 2025-03-01 - 1.1.1 - fix(package)
|
||||||
|
Update dependencies and pnpm configuration
|
||||||
|
|
||||||
|
- Updated @types/node to 22.13.8
|
||||||
|
- Updated pnpm configuration to include onlyBuiltDependencies with esbuild, mongodb-memory-server, and puppeteer
|
||||||
|
|
||||||
## 2025-03-01 - 1.1.0 - feat(core)
|
## 2025-03-01 - 1.1.0 - feat(core)
|
||||||
Introduce ProcessMonitor class and integrate native and external plugins
|
Introduce ProcessMonitor class and integrate native and external plugins
|
||||||
|
|
||||||
|
20
package.json
20
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@git.zone/tspm",
|
"name": "@git.zone/tspm",
|
||||||
"version": "1.1.0",
|
"version": "1.3.0",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "a no fuzz process manager",
|
"description": "a no fuzz process manager",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
@ -11,7 +11,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(tstest test/ --web)",
|
"test": "(tstest test/ --web)",
|
||||||
"build": "(tsbuild --web --allowimplicitany)",
|
"build": "(tsbuild --web --allowimplicitany)",
|
||||||
"buildDocs": "(tsdoc)"
|
"buildDocs": "(tsdoc)",
|
||||||
|
"start": "(tsrun ./cli.ts -v)"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsbuild": "^2.1.25",
|
"@git.zone/tsbuild": "^2.1.25",
|
||||||
@ -19,10 +20,14 @@
|
|||||||
"@git.zone/tsrun": "^1.2.46",
|
"@git.zone/tsrun": "^1.2.46",
|
||||||
"@git.zone/tstest": "^1.0.44",
|
"@git.zone/tstest": "^1.0.44",
|
||||||
"@push.rocks/tapbundle": "^5.0.15",
|
"@push.rocks/tapbundle": "^5.0.15",
|
||||||
"@types/node": "^20.8.7"
|
"@types/node": "^22.13.8"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@push.rocks/smartpath": "^5.0.18"
|
"@push.rocks/projectinfo": "^5.0.2",
|
||||||
|
"@push.rocks/smartcli": "^4.0.11",
|
||||||
|
"@push.rocks/smartpath": "^5.0.18",
|
||||||
|
"pidusage": "^4.0.0",
|
||||||
|
"ps-tree": "^1.2.0"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -45,6 +50,11 @@
|
|||||||
"readme.md"
|
"readme.md"
|
||||||
],
|
],
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"overrides": {}
|
"overrides": {},
|
||||||
|
"onlyBuiltDependencies": [
|
||||||
|
"esbuild",
|
||||||
|
"mongodb-memory-server",
|
||||||
|
"puppeteer"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1269
pnpm-lock.yaml
generated
1269
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
19
test/test.ts
19
test/test.ts
@ -6,3 +6,22 @@ tap.test('first test', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tap.start();
|
tap.start();
|
||||||
|
|
||||||
|
// Example usage:
|
||||||
|
const config: IMonitorConfig = {
|
||||||
|
name: 'Project XYZ Monitor', // Identifier for the instance
|
||||||
|
projectDir: '/path/to/your/project', // Set the project directory here
|
||||||
|
command: 'npm run xyz', // Full command string (no need for args)
|
||||||
|
memoryLimitBytes: 500 * 1024 * 1024, // 500 MB memory limit
|
||||||
|
monitorIntervalMs: 5000, // Check memory usage every 5 seconds
|
||||||
|
};
|
||||||
|
|
||||||
|
const monitor = new ProcessMonitor(config);
|
||||||
|
monitor.start();
|
||||||
|
|
||||||
|
// Ensure that on process exit (e.g. Ctrl+C) we clean up the child process and prevent respawns.
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
monitor.log('Received SIGINT, stopping monitor...');
|
||||||
|
monitor.stop();
|
||||||
|
process.exit();
|
||||||
|
});
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@git.zone/tspm',
|
name: '@git.zone/tspm',
|
||||||
version: '1.1.0',
|
version: '1.3.0',
|
||||||
description: 'a no fuzz process manager'
|
description: 'a no fuzz process manager'
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { spawn, ChildProcess } from 'child_process';
|
import * as plugins from './plugins.js';
|
||||||
import psTree from 'ps-tree';
|
|
||||||
import pidusage from 'pidusage';
|
|
||||||
|
|
||||||
interface IMonitorConfig {
|
export interface IMonitorConfig {
|
||||||
name?: string; // Optional name to identify the instance
|
name?: string; // Optional name to identify the instance
|
||||||
projectDir: string; // Directory where the command will run
|
projectDir: string; // Directory where the command will run
|
||||||
command: string; // Full command to run (e.g., "npm run xyz")
|
command: string; // Full command to run (e.g., "npm run xyz")
|
||||||
@ -11,8 +9,8 @@ interface IMonitorConfig {
|
|||||||
monitorIntervalMs?: number; // Interval (in ms) at which memory is checked (default: 5000)
|
monitorIntervalMs?: number; // Interval (in ms) at which memory is checked (default: 5000)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProcessMonitor {
|
export class ProcessMonitor {
|
||||||
private child: ChildProcess | null = null;
|
private child: plugins.childProcess.ChildProcess | null = null;
|
||||||
private config: IMonitorConfig;
|
private config: IMonitorConfig;
|
||||||
private intervalId: NodeJS.Timeout | null = null;
|
private intervalId: NodeJS.Timeout | null = null;
|
||||||
private stopped: boolean = true; // Initially stopped until start() is called
|
private stopped: boolean = true; // Initially stopped until start() is called
|
||||||
@ -46,7 +44,7 @@ class ProcessMonitor {
|
|||||||
', '
|
', '
|
||||||
)}] in directory: ${this.config.projectDir}`
|
)}] in directory: ${this.config.projectDir}`
|
||||||
);
|
);
|
||||||
this.child = spawn(this.config.command, this.config.args, {
|
this.child = plugins.childProcess.spawn(this.config.command, this.config.args, {
|
||||||
cwd: this.config.projectDir,
|
cwd: this.config.projectDir,
|
||||||
detached: true,
|
detached: true,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
@ -56,7 +54,7 @@ class ProcessMonitor {
|
|||||||
`Spawning command "${this.config.command}" in directory: ${this.config.projectDir}`
|
`Spawning command "${this.config.command}" in directory: ${this.config.projectDir}`
|
||||||
);
|
);
|
||||||
// Use shell mode to allow a full command string.
|
// Use shell mode to allow a full command string.
|
||||||
this.child = spawn(this.config.command, {
|
this.child = plugins.childProcess.spawn(this.config.command, {
|
||||||
cwd: this.config.projectDir,
|
cwd: this.config.projectDir,
|
||||||
detached: true,
|
detached: true,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
@ -107,11 +105,11 @@ class ProcessMonitor {
|
|||||||
*/
|
*/
|
||||||
private getProcessGroupMemory(pid: number): Promise<number> {
|
private getProcessGroupMemory(pid: number): Promise<number> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
psTree(pid, (err, children) => {
|
plugins.psTree(pid, (err, children) => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
// Include the main process and its children.
|
// Include the main process and its children.
|
||||||
const pids: number[] = [pid, ...children.map(child => Number(child.PID))];
|
const pids: number[] = [pid, ...children.map(child => Number(child.PID))];
|
||||||
pidusage(pids, (err, stats) => {
|
plugins.pidusage(pids, (err, stats) => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
let totalMemory = 0;
|
let totalMemory = 0;
|
||||||
for (const key in stats) {
|
for (const key in stats) {
|
||||||
@ -157,22 +155,3 @@ class ProcessMonitor {
|
|||||||
console.log(prefix + message);
|
console.log(prefix + message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example usage:
|
|
||||||
const config: IMonitorConfig = {
|
|
||||||
name: 'Project XYZ Monitor', // Identifier for the instance
|
|
||||||
projectDir: '/path/to/your/project', // Set the project directory here
|
|
||||||
command: 'npm run xyz', // Full command string (no need for args)
|
|
||||||
memoryLimitBytes: 500 * 1024 * 1024, // 500 MB memory limit
|
|
||||||
monitorIntervalMs: 5000, // Check memory usage every 5 seconds
|
|
||||||
};
|
|
||||||
|
|
||||||
const monitor = new ProcessMonitor(config);
|
|
||||||
monitor.start();
|
|
||||||
|
|
||||||
// Ensure that on process exit (e.g. Ctrl+C) we clean up the child process and prevent respawns.
|
|
||||||
process.on('SIGINT', () => {
|
|
||||||
monitor.log('Received SIGINT, stopping monitor...');
|
|
||||||
monitor.stop();
|
|
||||||
process.exit();
|
|
||||||
});
|
|
21
ts/cli.ts
Normal file
21
ts/cli.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import * as plugins from './plugins.js';
|
||||||
|
import * as paths from './paths.js';
|
||||||
|
|
||||||
|
export const run = async () => {
|
||||||
|
const tspmProjectinfo = new plugins.projectinfo.ProjectInfo(paths.packageDir);
|
||||||
|
|
||||||
|
const smartcliInstance = new plugins.smartcli.Smartcli();
|
||||||
|
smartcliInstance.addVersion(tspmProjectinfo.npm.version);
|
||||||
|
|
||||||
|
smartcliInstance.standardCommand().subscribe({
|
||||||
|
next: (argvArg) => {
|
||||||
|
console.log(`Please specify a command.`)
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
smartcliInstance.addCommand('restart').subscribe({
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
smartcliInstance.startParse();
|
||||||
|
}
|
12
ts/index.ts
12
ts/index.ts
@ -1,3 +1,11 @@
|
|||||||
import * as plugins from './plugins.js';
|
export * from './classes.tspm.js';
|
||||||
|
export * from './classes.processmonitor.js';
|
||||||
|
|
||||||
export let demoExport = 'Hi there! :) This is an exported string';
|
import * as cli from './cli.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called to run as cli
|
||||||
|
*/
|
||||||
|
export const runCli = async () => {
|
||||||
|
await cli.run();
|
||||||
|
}
|
4
ts/paths.ts
Normal file
4
ts/paths.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import * as plugins from './plugins.js';
|
||||||
|
|
||||||
|
export const packageDir = plugins.path.join(plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), '..');
|
||||||
|
export const cwd = process.cwd();
|
@ -1,13 +1,28 @@
|
|||||||
// native scope
|
// native scope
|
||||||
|
import * as childProcess from 'child_process';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
childProcess,
|
||||||
path,
|
path,
|
||||||
}
|
}
|
||||||
|
|
||||||
// @push.rocks scope
|
// @push.rocks scope
|
||||||
|
import * as projectinfo from '@push.rocks/projectinfo';
|
||||||
import * as smartpath from '@push.rocks/smartpath';
|
import * as smartpath from '@push.rocks/smartpath';
|
||||||
|
import * as smartcli from '@push.rocks/smartcli';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
projectinfo,
|
||||||
smartpath,
|
smartpath,
|
||||||
|
smartcli,
|
||||||
|
}
|
||||||
|
|
||||||
|
// third-party scope
|
||||||
|
import psTree from 'ps-tree';
|
||||||
|
import pidusage from 'pidusage';
|
||||||
|
|
||||||
|
export {
|
||||||
|
psTree,
|
||||||
|
pidusage,
|
||||||
}
|
}
|
Reference in New Issue
Block a user