diff --git a/lib/API/schema.json b/lib/API/schema.json index fc5f868cd..5bc7db42c 100644 --- a/lib/API/schema.json +++ b/lib/API/schema.json @@ -148,6 +148,11 @@ "docDefault": false, "docDescription": "Make the process wait for a process.send('ready')" }, + "launch_limit": { + "type": "number", + "docDefault": 1, + "docDescription": "Maximum number of launching processes at a time" + }, "instances": { "type": "number", "docDefault": 1, diff --git a/lib/God.js b/lib/God.js index 620e5b5d4..ce4f99b54 100644 --- a/lib/God.js +++ b/lib/God.js @@ -136,7 +136,14 @@ God.prepare = function prepare (env, cb) { env.instances = 1; } - timesLimit(env.instances, 1, function (n, next) { + // app launch in parallel limit + if (env.launch_limit != null) { + env.launch_limit = parseInt(env.launch_limit); + } + if (!env.launch_limit || env.launch_limit < 0) { + env.launch_limit = 1; + } + timesLimit(env.instances, env.launch_limit, function (n, next) { env.vizion_running = false; if (env.env && env.env.vizion_running) { env.env.vizion_running = false; diff --git a/test/programmatic/graceful.mocha.js b/test/programmatic/graceful.mocha.js index 91de677c6..a64f74f08 100644 --- a/test/programmatic/graceful.mocha.js +++ b/test/programmatic/graceful.mocha.js @@ -173,6 +173,70 @@ describe('Wait ready / Graceful start / restart', function() { }); + describe('(Cluster): Launching limit feature', function () { + this.timeout(10000); + + after(function(done) { + pm2.delete('all', done); + }); + + it('Should launch app processes in parallel', function(done) { + pm2.start({ + script : './wait-ready.js', + instances : 3, + launch_limit: 2, + exec_mode : 'cluster', + name : 'launching-limit-1' + }); + + setTimeout(function() { + pm2.list(function(err, apps) { + should(apps[0].pm2_env.status).eql('online'); + should(apps[1].pm2_env.status).eql('online'); + should(apps[2].pm2_env.status).eql('online'); + pm2.delete('all', done); + }) + }, 500); + }); + + it('Should launch app processes in parallel and limit launching processes on wait ready', function(done) { + pm2.start({ + script : './wait-ready.js', + listen_timeout : 2000, + wait_ready : true, + instances : 3, + launch_limit: 2, + exec_mode : 'cluster', + name : 'launching-limit-2' + }); + + setTimeout(function() { + pm2.list(function(err, apps) { + should(apps[0].pm2_env.status).eql('launching'); + should(apps[1].pm2_env.status).eql('launching'); + should(apps[2]).undefined(); + }); + }, 500); + + setTimeout(function() { + pm2.list(function(err, apps) { + should(apps[0].pm2_env.status).eql('online'); + should(apps[1].pm2_env.status).eql('online'); + should(apps[2].pm2_env.status).eql('launching'); + }) + }, 1500); + + setTimeout(function() { + pm2.list(function(err, apps) { + should(apps[0].pm2_env.status).eql('online'); + should(apps[1].pm2_env.status).eql('online'); + should(apps[2].pm2_env.status).eql('online'); + done(); + }) + }, 2500); + }); + }); + describe('(Cluster): Wait ready feature', function () { this.timeout(10000); diff --git a/types/index.d.ts b/types/index.d.ts index 5b98aa28a..c4749fd7d 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -383,6 +383,10 @@ export interface StartOptions { * when you want your application to be considered as ready. */ wait_ready?: boolean; + /** + * (Default: 1) Maximum number of launching processes at a time on application startup. + */ + launch_limit?: number; /** * (Default: 1600) * The number of milliseconds to wait after a stop or restart command issues a SIGINT signal to kill the @@ -446,7 +450,7 @@ export interface StartOptions { interface ReloadOptions { /** - * (Default: false) If true is passed in, pm2 will reload it’s environment from process.env + * (Default: false) If true is passed in, pm2 will reload it’s environment from process.env * before reloading your process. */ updateEnv?: boolean;