From 9e1b5818ae253e031bbf4fd37414b2f7aa6ad816 Mon Sep 17 00:00:00 2001 From: TZ Date: Sat, 25 Nov 2017 21:36:02 +0800 Subject: [PATCH 1/4] feat: support stop --title --- README.md | 4 +++- lib/cmd/start.js | 2 +- lib/cmd/stop.js | 13 +++++++++++-- package.json | 12 ++++++------ test/stop.test.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ce7c284..97bcb16 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ $ eggctl start [options] [baseDir] - `baseDir` - directory of application, default to `process.cwd()`. - **Options** - `port` - listening port, default to `process.env.PORT`, if unset, egg will use `7001` as default. - - `title` - process title description, use for kill grep, default to `egg-server-APPNAME`. + - `title` - process title description, use for kill grep, default to `egg-server-${APP_NAME}`. - `workers` - numbers of app workers, default to `process.env.EGG_WORKERS`, if unset, egg will use `os.cpus().length` as default. - `daemon` - whether run at background daemon mode. - `framework` - specify framework that can be absolute path or npm package, default to auto detect. @@ -67,3 +67,5 @@ $ eggctl stop [baseDir] - **Arguments** - `baseDir` - directory of application, default to `process.cwd()`. +- **Options** + - `title` - process title description, use for kill grep, default to `egg-server-${APP_NAME}`. \ No newline at end of file diff --git a/lib/cmd/start.js b/lib/cmd/start.js index 53361bc..09fbd50 100644 --- a/lib/cmd/start.js +++ b/lib/cmd/start.js @@ -19,7 +19,7 @@ class StartCommand extends Command { this.options = { title: { - description: 'process title description, use for kill grep, default to `egg-server-APPNAME`', + description: 'process title description, use for kill grep, default to `egg-server-${APP_NAME}`', type: 'string', }, workers: { diff --git a/lib/cmd/stop.js b/lib/cmd/stop.js index ec5fb56..b8b4eda 100644 --- a/lib/cmd/stop.js +++ b/lib/cmd/stop.js @@ -10,6 +10,12 @@ class StopCommand extends Command { super(rawArgv); this.usage = 'Usage: egg-scripts stop [baseDir]'; this.serverBin = path.join(__dirname, '../start-cluster'); + this.options = { + title: { + description: 'process title description, use for kill grep, default to `egg-server-${APP_NAME}`', + type: 'string', + }, + }; } get description() { @@ -32,12 +38,15 @@ class StopCommand extends Command { if (!path.isAbsolute(baseDir)) baseDir = path.join(context.cwd, baseDir); argv.baseDir = baseDir; + const pkgInfo = require(path.join(baseDir, 'package.json')); + argv.title = argv.title || `egg-server-${pkgInfo.name}`; + this.logger.info(`stopping egg application at ${baseDir}`); // node /Users/tz/Workspaces/eggjs/egg-scripts/lib/start-cluster {"title":"egg-server","workers":4,"port":7001,"baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg"} let processList = yield this.helper.findNodeProcess(item => { const cmd = item.cmd; - return cmd.includes('start-cluster'); + return cmd.includes('start-cluster') && cmd.includes(`"title":"${argv.title}"`); }); let pids = processList.map(x => x.pid); @@ -55,7 +64,7 @@ class StopCommand extends Command { // node /Users/tz/Workspaces/eggjs/test/showcase/node_modules/_egg-cluster@1.8.0@egg-cluster/lib/app_worker.js {"framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg","baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","port":7001,"workers":2,"plugins":null,"https":false,"key":"","cert":"","title":"egg-server","clusterPort":52406} processList = yield this.helper.findNodeProcess(item => { const cmd = item.cmd; - return cmd.includes('egg-cluster/lib/app_worker.js') || cmd.includes('egg-cluster/lib/agent_worker.js'); + return cmd.includes(`"title":"${argv.title}"`) && (cmd.includes('egg-cluster/lib/app_worker.js') || cmd.includes('egg-cluster/lib/agent_worker.js')); }); pids = processList.map(x => x.pid); diff --git a/package.json b/package.json index 294a525..2d203f0 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ }, "dependencies": { "common-bin": "^2.7.1", - "egg-utils": "^2.2.0", - "moment": "^2.19.1", + "egg-utils": "^2.3.0", + "moment": "^2.19.2", "mz": "^2.7.0", "mz-modules": "^2.0.0", "node-homedir": "^1.1.0", @@ -18,15 +18,15 @@ "zlogger": "^1.1.0" }, "devDependencies": { - "autod": "^2.10.1", + "autod": "^3.0.1", "coffee": "^4.1.0", - "egg": "^1.9.0", + "egg": "^2.0.0", "egg-bin": "^4.3.5", "egg-ci": "^1.8.0", - "eslint": "^4.8.0", + "eslint": "^4.11.0", "eslint-config-egg": "^5.1.1", "mm": "^2.2.0", - "urllib": "^2.25.0", + "urllib": "^2.25.1", "webstorm-disable-index": "^1.2.0" }, "engines": { diff --git a/test/stop.test.js b/test/stop.test.js index bb79773..ffe17c0 100644 --- a/test/stop.test.js +++ b/test/stop.test.js @@ -165,4 +165,53 @@ describe('test/stop.test.js', () => { .end(); }); }); + + describe('stop --title', () => { + let app; + let killer; + + beforeEach(function* () { + yield utils.cleanup(fixturePath); + app = coffee.fork(eggBin, [ 'start', '--workers=2', '--title=example', fixturePath ]); + // app.debug(); + app.expect('code', 0); + yield sleep(waitTime); + + assert(app.stderr === ''); + assert(app.stdout.match(/custom-framework started on http:\/\/127\.0\.0\.1:7001/)); + const result = yield httpclient.request('http://127.0.0.1:7001'); + assert(result.data.toString() === 'hi, egg'); + }); + + afterEach(function* () { + app.proc.kill('SIGTERM'); + yield utils.cleanup(fixturePath); + }); + + it('should stop', function* () { + yield coffee.fork(eggBin, [ 'stop', fixturePath ]) + .debug() + .expect('stdout', new RegExp(`\\[egg-scripts] stopping egg application at ${fixturePath}`)) + .expect('stderr', /can't detect any running egg process/) + .expect('code', 0) + .end(); + + killer = coffee.fork(eggBin, [ 'stop', '--title=example' ], { cwd: fixturePath }); + killer.debug(); + killer.expect('code', 0); + + // yield killer.end(); + yield sleep(waitTime); + + // make sure is kill not auto exist + assert(!app.stdout.includes('exist by env')); + + assert(app.stdout.includes('[master] receive signal SIGTERM, closing')); + assert(app.stdout.includes('[master] exit with code:0')); + assert(app.stdout.includes('[app_worker] exit with code:0')); + // assert(app.stdout.includes('[agent_worker] exit with code:0')); + assert(killer.stdout.includes(`[egg-scripts] stopping egg application at ${fixturePath}`)); + assert(killer.stdout.match(/got master pid \["\d+\"\]/i)); + }); + }); }); From d7520dcbda10531b513e84156bbba64f48f4afc1 Mon Sep 17 00:00:00 2001 From: TZ Date: Tue, 28 Nov 2017 09:20:44 +0800 Subject: [PATCH 2/4] chore: revert to egg@1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2d203f0..fe17c02 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "devDependencies": { "autod": "^3.0.1", "coffee": "^4.1.0", - "egg": "^2.0.0", + "egg": "^1.11.0", "egg-bin": "^4.3.5", "egg-ci": "^1.8.0", "eslint": "^4.11.0", From e858281113cf34b59640c4a57fbf7112dbe06f6d Mon Sep 17 00:00:00 2001 From: TZ Date: Tue, 28 Nov 2017 11:30:32 +0800 Subject: [PATCH 3/4] feat: remove stop baseDir --- README.md | 7 +-- lib/cmd/stop.js | 20 ++----- test/stop.test.js | 141 +++++++++++++++++++++++++--------------------- 3 files changed, 84 insertions(+), 84 deletions(-) diff --git a/README.md b/README.md index 97bcb16..1b7e96a 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,8 @@ Stop egg gracefull. ```bash # stop egg -$ eggctl stop [baseDir] -# eggctl stop ./server +$ eggctl stop [--title=example] ``` -- **Arguments** - - `baseDir` - directory of application, default to `process.cwd()`. - **Options** - - `title` - process title description, use for kill grep, default to `egg-server-${APP_NAME}`. \ No newline at end of file + - `title` - process title description, use for kill grep. \ No newline at end of file diff --git a/lib/cmd/stop.js b/lib/cmd/stop.js index b8b4eda..517d37d 100644 --- a/lib/cmd/stop.js +++ b/lib/cmd/stop.js @@ -8,11 +8,11 @@ class StopCommand extends Command { constructor(rawArgv) { super(rawArgv); - this.usage = 'Usage: egg-scripts stop [baseDir]'; + this.usage = 'Usage: egg-scripts stop [--title=example]'; this.serverBin = path.join(__dirname, '../start-cluster'); this.options = { title: { - description: 'process title description, use for kill grep, default to `egg-server-${APP_NAME}`', + description: 'process title description, use for kill grep', type: 'string', }, }; @@ -31,22 +31,12 @@ class StopCommand extends Command { const { argv } = context; - // egg-script stop - // egg-script stop ./server - // egg-script stop /opt/app - let baseDir = argv._[0] || context.cwd; - if (!path.isAbsolute(baseDir)) baseDir = path.join(context.cwd, baseDir); - argv.baseDir = baseDir; - - const pkgInfo = require(path.join(baseDir, 'package.json')); - argv.title = argv.title || `egg-server-${pkgInfo.name}`; - - this.logger.info(`stopping egg application at ${baseDir}`); + this.logger.info(`stopping egg application ${argv.title ? `with --title=${argv.title}` : ''}`); // node /Users/tz/Workspaces/eggjs/egg-scripts/lib/start-cluster {"title":"egg-server","workers":4,"port":7001,"baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg"} let processList = yield this.helper.findNodeProcess(item => { const cmd = item.cmd; - return cmd.includes('start-cluster') && cmd.includes(`"title":"${argv.title}"`); + return cmd.includes('start-cluster') && (!argv.title || cmd.includes(`"title":"${argv.title}"`)); }); let pids = processList.map(x => x.pid); @@ -64,7 +54,7 @@ class StopCommand extends Command { // node /Users/tz/Workspaces/eggjs/test/showcase/node_modules/_egg-cluster@1.8.0@egg-cluster/lib/app_worker.js {"framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg","baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","port":7001,"workers":2,"plugins":null,"https":false,"key":"","cert":"","title":"egg-server","clusterPort":52406} processList = yield this.helper.findNodeProcess(item => { const cmd = item.cmd; - return cmd.includes(`"title":"${argv.title}"`) && (cmd.includes('egg-cluster/lib/app_worker.js') || cmd.includes('egg-cluster/lib/agent_worker.js')); + return (!argv.title || cmd.includes(`"title":"${argv.title}"`)) && (cmd.includes('egg-cluster/lib/app_worker.js') || cmd.includes('egg-cluster/lib/agent_worker.js')); }); pids = processList.map(x => x.pid); diff --git a/test/stop.test.js b/test/stop.test.js index ffe17c0..d623700 100644 --- a/test/stop.test.js +++ b/test/stop.test.js @@ -49,67 +49,23 @@ describe('test/stop.test.js', () => { yield utils.cleanup(fixturePath); }); - describe('full path', () => { - it('should stop', function* () { - killer = coffee.fork(eggBin, [ 'stop', fixturePath ]); - killer.debug(); - killer.expect('code', 0); - - // yield killer.end(); - yield sleep(waitTime); - - // make sure is kill not auto exist - assert(!app.stdout.includes('exist by env')); - - assert(app.stdout.includes('[master] receive signal SIGTERM, closing')); - assert(app.stdout.includes('[master] exit with code:0')); - assert(app.stdout.includes('[app_worker] exit with code:0')); - // assert(app.stdout.includes('[agent_worker] exit with code:0')); - assert(killer.stdout.includes(`[egg-scripts] stopping egg application at ${fixturePath}`)); - assert(killer.stdout.match(/got master pid \["\d+\"\]/i)); - }); - }); + it('should stop', function* () { + killer = coffee.fork(eggBin, [ 'stop', fixturePath ]); + killer.debug(); + killer.expect('code', 0); - describe('relative path', () => { - it('should stop', function* () { - killer = coffee.fork(eggBin, [ 'stop', path.relative(process.cwd(), fixturePath) ]); - killer.debug(); - killer.expect('code', 0); - - // yield killer.end(); - yield sleep(waitTime); - - // make sure is kill not auto exist - assert(!app.stdout.includes('exist by env')); - - assert(app.stdout.includes('[master] receive signal SIGTERM, closing')); - assert(app.stdout.includes('[master] exit with code:0')); - assert(app.stdout.includes('[app_worker] exit with code:0')); - // assert(app.stdout.includes('[agent_worker] exit with code:0')); - assert(killer.stdout.includes(`[egg-scripts] stopping egg application at ${fixturePath}`)); - assert(killer.stdout.match(/got master pid \["\d+\"\]/i)); - }); - }); + // yield killer.end(); + yield sleep(waitTime); - describe('without baseDir', () => { - it('should stop', function* () { - killer = coffee.fork(eggBin, [ 'stop' ], { cwd: fixturePath }); - killer.debug(); - killer.expect('code', 0); - - // yield killer.end(); - yield sleep(waitTime); - - // make sure is kill not auto exist - assert(!app.stdout.includes('exist by env')); - - assert(app.stdout.includes('[master] receive signal SIGTERM, closing')); - assert(app.stdout.includes('[master] exit with code:0')); - assert(app.stdout.includes('[app_worker] exit with code:0')); - // assert(app.stdout.includes('[agent_worker] exit with code:0')); - assert(killer.stdout.includes(`[egg-scripts] stopping egg application at ${fixturePath}`)); - assert(killer.stdout.match(/got master pid \["\d+\"\]/i)); - }); + // make sure is kill not auto exist + assert(!app.stdout.includes('exist by env')); + + assert(app.stdout.includes('[master] receive signal SIGTERM, closing')); + assert(app.stdout.includes('[master] exit with code:0')); + assert(app.stdout.includes('[app_worker] exit with code:0')); + // assert(app.stdout.includes('[agent_worker] exit with code:0')); + assert(killer.stdout.includes('[egg-scripts] stopping egg application')); + assert(killer.stdout.match(/got master pid \["\d+\"\]/i)); }); }); @@ -132,7 +88,7 @@ describe('test/stop.test.js', () => { it('should stop', function* () { yield coffee.fork(eggBin, [ 'stop', fixturePath ]) .debug() - .expect('stdout', new RegExp(`\\[egg-scripts] stopping egg application at ${fixturePath}`)) + .expect('stdout', /\[egg-scripts] stopping egg application/) .expect('stdout', /got master pid \["\d+\"\]/i) .expect('code', 0) .end(); @@ -159,7 +115,7 @@ describe('test/stop.test.js', () => { yield utils.cleanup(fixturePath); yield coffee.fork(eggBin, [ 'stop', fixturePath ]) .debug() - .expect('stdout', new RegExp(`\\[egg-scripts] stopping egg application at ${fixturePath}`)) + .expect('stdout', /\[egg-scripts] stopping egg application/) .expect('stderr', /can't detect any running egg process/) .expect('code', 0) .end(); @@ -189,9 +145,9 @@ describe('test/stop.test.js', () => { }); it('should stop', function* () { - yield coffee.fork(eggBin, [ 'stop', fixturePath ]) + yield coffee.fork(eggBin, [ 'stop', '--title=random', fixturePath ]) .debug() - .expect('stdout', new RegExp(`\\[egg-scripts] stopping egg application at ${fixturePath}`)) + .expect('stdout', /\[egg-scripts] stopping egg application with --title=random/) .expect('stderr', /can't detect any running egg process/) .expect('code', 0) .end(); @@ -210,8 +166,65 @@ describe('test/stop.test.js', () => { assert(app.stdout.includes('[master] exit with code:0')); assert(app.stdout.includes('[app_worker] exit with code:0')); // assert(app.stdout.includes('[agent_worker] exit with code:0')); - assert(killer.stdout.includes(`[egg-scripts] stopping egg application at ${fixturePath}`)); + assert(killer.stdout.includes('[egg-scripts] stopping egg application with --title=example')); assert(killer.stdout.match(/got master pid \["\d+\"\]/i)); }); }); + + describe('stop all', () => { + let app; + let app2; + let killer; + + beforeEach(function* () { + yield utils.cleanup(fixturePath); + app = coffee.fork(eggBin, [ 'start', '--workers=2', '--title=example', fixturePath ]); + // app.debug(); + app.expect('code', 0); + + app2 = coffee.fork(eggBin, [ 'start', '--workers=2', '--title=test', '--port=7002', fixturePath ]); + app2.expect('code', 0); + + yield sleep(waitTime); + + assert(app.stderr === ''); + assert(app.stdout.match(/custom-framework started on http:\/\/127\.0\.0\.1:7001/)); + const result = yield httpclient.request('http://127.0.0.1:7001'); + assert(result.data.toString() === 'hi, egg'); + + assert(app2.stderr === ''); + assert(app2.stdout.match(/custom-framework started on http:\/\/127\.0\.0\.1:7002/)); + const result2 = yield httpclient.request('http://127.0.0.1:7002'); + assert(result2.data.toString() === 'hi, egg'); + }); + + afterEach(function* () { + app.proc.kill('SIGTERM'); + app2.proc.kill('SIGTERM'); + yield utils.cleanup(fixturePath); + }); + + it('should stop', function* () { + killer = coffee.fork(eggBin, [ 'stop' ], { cwd: fixturePath }); + killer.debug(); + killer.expect('code', 0); + + // yield killer.end(); + yield sleep(waitTime); + + // make sure is kill not auto exist + assert(!app.stdout.includes('exist by env')); + assert(app.stdout.includes('[master] receive signal SIGTERM, closing')); + assert(app.stdout.includes('[master] exit with code:0')); + assert(app.stdout.includes('[app_worker] exit with code:0')); + // assert(app.stdout.includes('[agent_worker] exit with code:0')); + assert(killer.stdout.includes('[egg-scripts] stopping egg application')); + assert(killer.stdout.match(/got master pid \["\d+\","\d+\"\]/i)); + + assert(!app2.stdout.includes('exist by env')); + assert(app2.stdout.includes('[master] receive signal SIGTERM, closing')); + assert(app2.stdout.includes('[master] exit with code:0')); + assert(app2.stdout.includes('[app_worker] exit with code:0')); + }); + }); }); From 58d2feb5a809565db9072dc546b965bc0dfd1d47 Mon Sep 17 00:00:00 2001 From: TZ Date: Tue, 28 Nov 2017 15:14:59 +0800 Subject: [PATCH 4/4] f --- lib/cmd/stop.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/cmd/stop.js b/lib/cmd/stop.js index 517d37d..09585c8 100644 --- a/lib/cmd/stop.js +++ b/lib/cmd/stop.js @@ -36,7 +36,9 @@ class StopCommand extends Command { // node /Users/tz/Workspaces/eggjs/egg-scripts/lib/start-cluster {"title":"egg-server","workers":4,"port":7001,"baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg"} let processList = yield this.helper.findNodeProcess(item => { const cmd = item.cmd; - return cmd.includes('start-cluster') && (!argv.title || cmd.includes(`"title":"${argv.title}"`)); + return argv.title ? + cmd.includes('start-cluster') && cmd.includes(`"title":"${argv.title}"`) : + cmd.includes('start-cluster'); }); let pids = processList.map(x => x.pid); @@ -54,7 +56,9 @@ class StopCommand extends Command { // node /Users/tz/Workspaces/eggjs/test/showcase/node_modules/_egg-cluster@1.8.0@egg-cluster/lib/app_worker.js {"framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg","baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","port":7001,"workers":2,"plugins":null,"https":false,"key":"","cert":"","title":"egg-server","clusterPort":52406} processList = yield this.helper.findNodeProcess(item => { const cmd = item.cmd; - return (!argv.title || cmd.includes(`"title":"${argv.title}"`)) && (cmd.includes('egg-cluster/lib/app_worker.js') || cmd.includes('egg-cluster/lib/agent_worker.js')); + return argv.title ? + (cmd.includes('egg-cluster/lib/app_worker.js') || cmd.includes('egg-cluster/lib/agent_worker.js')) && cmd.includes(`"title":"${argv.title}"`) : + (cmd.includes('egg-cluster/lib/app_worker.js') || cmd.includes('egg-cluster/lib/agent_worker.js')); }); pids = processList.map(x => x.pid);