frosty 0.0.149 → 0.0.150
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -44,6 +44,7 @@ print_usage() {
|
|
|
44
44
|
echo " -B, --no-build Skip build step"
|
|
45
45
|
echo " -p, --port <port> Specify port for the server (default: 8080)"
|
|
46
46
|
echo " -n, --num-workers <count> Specify number of worker processes"
|
|
47
|
+
echo " -i, --instance-var <name> Specify the env variable name for worker instance index (default: NODE_APP_INSTANCE)"
|
|
47
48
|
echo " -c, --configuration <file> Specify configuration file to use (default: server.config.js)"
|
|
48
49
|
echo " -s, --src <dir> Specify source root directory"
|
|
49
50
|
echo " -o, --output <dir> Specify output directory for build artifacts"
|
|
@@ -66,6 +67,7 @@ while [ $# -gt 0 ]; do
|
|
|
66
67
|
-B|--no-build) NO_BUILD=true; shift ;;
|
|
67
68
|
-p|--port) PORT="$2"; shift 2 ;;
|
|
68
69
|
-n|--num-workers) NUM_WORKERS="$2"; shift 2 ;;
|
|
70
|
+
-i|--instance-var) INSTANCE_VAR="$2"; shift 2 ;;
|
|
69
71
|
-c|--configuration) CONFIG_FILE="$2"; shift 2 ;;
|
|
70
72
|
-s|--src) SRCROOT="$2"; shift 2 ;;
|
|
71
73
|
-o|--output) OUTPUT_DIR="$2"; shift 2 ;;
|
|
@@ -114,6 +116,7 @@ if [ "$NO_BUILD" != "true" ]; then
|
|
|
114
116
|
[ -n "$INPUT_FILE" ] && BUILD_OPTS="$BUILD_OPTS --env INPUT_FILE="$INPUT_FILE""
|
|
115
117
|
[ -n "$SRCROOT" ] && BUILD_OPTS="$BUILD_OPTS --env SRCROOT="$SRCROOT""
|
|
116
118
|
[ -n "$NUM_WORKERS" ] && BUILD_OPTS="$BUILD_OPTS --env NUM_WORKERS="$NUM_WORKERS""
|
|
119
|
+
[ -n "$INSTANCE_VAR" ] && BUILD_OPTS="$BUILD_OPTS --env INSTANCE_VAR="$INSTANCE_VAR""
|
|
117
120
|
[ -n "$PORT" ] && BUILD_OPTS="$BUILD_OPTS --env PORT="$PORT""
|
|
118
121
|
if [ "$WATCH_MODE" = "true" ]; then
|
|
119
122
|
node "$FROSTY_CLI_ROOT/node_modules/webpack-cli/bin/cli.js" $BUILD_OPTS --watch &
|
|
@@ -28,3 +28,4 @@ import { availableParallelism } from 'os';
|
|
|
28
28
|
|
|
29
29
|
export const PORT = process.env.PORT ? parseInt(process.env.PORT) : 8080;
|
|
30
30
|
export const NUM_WORKERS = process.env.NUM_WORKERS ? parseInt(process.env.NUM_WORKERS) : availableParallelism();
|
|
31
|
+
export const INSTANCE_VAR = process.env.INSTANCE_VAR || 'NODE_APP_INSTANCE';
|
|
@@ -31,18 +31,44 @@ import { Server } from '@o2ter/server-js';
|
|
|
31
31
|
import { FrostyRoute } from './route';
|
|
32
32
|
import * as __SERVER__ from '__SERVER__';
|
|
33
33
|
import * as __APPLICATIONS__ from '__APPLICATIONS__';
|
|
34
|
-
import { PORT, NUM_WORKERS } from './env';
|
|
34
|
+
import { PORT, NUM_WORKERS, INSTANCE_VAR } from './env';
|
|
35
35
|
|
|
36
36
|
if (cluster.isPrimary && NUM_WORKERS > 1) {
|
|
37
|
-
console.
|
|
37
|
+
console.info(`Primary ${process.pid} is running`);
|
|
38
38
|
|
|
39
|
-
// Fork workers.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
// Fork workers one by one, waiting for each to come online before starting the next.
|
|
40
|
+
let forked = 0;
|
|
41
|
+
const workerInstances = new Map(); // worker.id -> instance index
|
|
42
|
+
const startedWorkers = new Set(); // worker IDs that have successfully started
|
|
43
|
+
|
|
44
|
+
const spawnWorker = (instance) => {
|
|
45
|
+
const worker = cluster.fork({ [INSTANCE_VAR]: instance });
|
|
46
|
+
workerInstances.set(worker.id, instance);
|
|
47
|
+
return worker;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const forkNext = () => {
|
|
51
|
+
if (forked >= NUM_WORKERS) return;
|
|
52
|
+
const instance = forked++;
|
|
53
|
+
const worker = spawnWorker(instance);
|
|
54
|
+
worker.once('listening', () => {
|
|
55
|
+
startedWorkers.add(worker.id);
|
|
56
|
+
forkNext();
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
forkNext();
|
|
43
60
|
|
|
44
61
|
cluster.on('exit', (worker, code, signal) => {
|
|
45
|
-
console.
|
|
62
|
+
console.info(`Process ${worker.process.pid} exited with code ${code} (${signal})`);
|
|
63
|
+
const instance = workerInstances.get(worker.id);
|
|
64
|
+
workerInstances.delete(worker.id);
|
|
65
|
+
if (startedWorkers.delete(worker.id)) {
|
|
66
|
+
// Worker had started successfully; restart it
|
|
67
|
+
const newWorker = spawnWorker(instance);
|
|
68
|
+
newWorker.once('listening', () => {
|
|
69
|
+
startedWorkers.add(newWorker.id);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
46
72
|
});
|
|
47
73
|
|
|
48
74
|
} else {
|
|
@@ -43,6 +43,7 @@ export default async (env, argv) => {
|
|
|
43
43
|
INPUT_FILE,
|
|
44
44
|
PORT = 8080,
|
|
45
45
|
NUM_WORKERS,
|
|
46
|
+
INSTANCE_VAR,
|
|
46
47
|
} = env;
|
|
47
48
|
|
|
48
49
|
const serverConfig = await (async () => {
|
|
@@ -254,7 +255,7 @@ export default async (env, argv) => {
|
|
|
254
255
|
optimization: webpackOptimization({ server: true }),
|
|
255
256
|
plugins: _.compact([
|
|
256
257
|
...webpackPlugins,
|
|
257
|
-
new webpack.EnvironmentPlugin({ PORT, NUM_WORKERS }),
|
|
258
|
+
new webpack.EnvironmentPlugin({ PORT, NUM_WORKERS, INSTANCE_VAR }),
|
|
258
259
|
new webpack.DefinePlugin({
|
|
259
260
|
__applications__: JSON.stringify(_.mapValues(inputs, x => ({
|
|
260
261
|
path: x.basepath,
|