Skip to content

Commit 4d78446

Browse files
authored
Adds --cluster support (#2596)
* Adds --cluster support * Restart failing child processes
1 parent d65f4a6 commit 4d78446

File tree

2 files changed

+48
-16
lines changed

2 files changed

+48
-16
lines changed

src/cli/cli-definitions.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,5 +221,9 @@ export default {
221221
env: "PARSE_SERVER_SCHEMA_CACHE_TTL",
222222
help: "The TTL for caching the schema for optimizing read/write operations. You should put a long TTL when your DB is in production. default to 0; disabled.",
223223
action: numberParser("schemaCacheTTL"),
224+
},
225+
"cluster": {
226+
help: "Run with cluster, optionally set the number of processes default to os.cpus().length",
227+
action: numberParser("cluster"),
224228
}
225229
};

src/cli/parse-server.js

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { ParseServer } from '../index';
44
import definitions from './cli-definitions';
55
import program from './utils/commander';
66
import { mergeWithOptions } from './utils/commander';
7+
import cluster from 'cluster';
8+
import os from 'os';
79

810
program.loadDefinitions(definitions);
911

@@ -48,28 +50,54 @@ if (!options.appId || !options.masterKey || !options.serverURL) {
4850
process.exit(1);
4951
}
5052

51-
const app = express();
52-
const api = new ParseServer(options);
53-
app.use(options.mountPath, api);
54-
55-
var server = app.listen(options.port, function() {
56-
53+
function logStartupOptions(options) {
5754
for (let key in options) {
5855
let value = options[key];
5956
if (key == "masterKey") {
6057
value = "***REDACTED***";
6158
}
6259
console.log(`${key}: ${value}`);
6360
}
64-
console.log('');
65-
console.log('parse-server running on '+options.serverURL);
66-
});
61+
}
62+
63+
function startServer(options, callback) {
64+
const app = express();
65+
const api = new ParseServer(options);
66+
app.use(options.mountPath, api);
67+
68+
var server = app.listen(options.port, callback);
6769

68-
var handleShutdown = function() {
69-
console.log('Termination signal received. Shutting down.');
70-
server.close(function () {
71-
process.exit(0);
70+
var handleShutdown = function() {
71+
console.log('Termination signal received. Shutting down.');
72+
server.close(function () {
73+
process.exit(0);
74+
});
75+
};
76+
process.on('SIGTERM', handleShutdown);
77+
process.on('SIGINT', handleShutdown);
78+
}
79+
80+
if (options.cluster) {
81+
const numCPUs = typeof options.cluster === 'number' ? options.cluster : os.cpus().length;
82+
if (cluster.isMaster) {
83+
logStartupOptions(options);
84+
for(var i = 0; i < numCPUs; i++) {
85+
cluster.fork();
86+
}
87+
cluster.on('exit', (worker, code, signal) => {
88+
console.log(`worker ${worker.process.pid} died... Restarting`);
89+
cluster.fork();
90+
});
91+
} else {
92+
startServer(options, () => {
93+
console.log('['+process.pid+'] parse-server running on '+options.serverURL);
94+
});
95+
}
96+
} else {
97+
startServer(options, () => {
98+
logStartupOptions(options);
99+
console.log('');
100+
console.log('['+process.pid+'] parse-server running on '+options.serverURL);
72101
});
73-
};
74-
process.on('SIGTERM', handleShutdown);
75-
process.on('SIGINT', handleShutdown);
102+
}
103+

0 commit comments

Comments
 (0)