Fix process shutdown issues
This commit is contained in:
1 parent
4bcee572f1
commit
ed0aa8ae7a
9 files changed
+63
-44
No files matched your search
+7
-4
@@ -35,10 +35,13 @@ const SERVICE_ADDRESS = config.get("CWMP_INTERFACE");
|
|||||||
const SERVICE_PORT = config.get("CWMP_PORT");
|
const SERVICE_PORT = config.get("CWMP_PORT");
|
||||||
|
|
||||||
function exitWorkerGracefully(): void {
|
function exitWorkerGracefully(): void {
|
||||||
db.disconnect();
|
setTimeout(exitWorkerUngracefully, 5000).unref();
|
||||||
cache.disconnect();
|
Promise.all([
|
||||||
extensions.killAll();
|
db.disconnect(),
|
||||||
cluster.worker.disconnect();
|
cache.disconnect(),
|
||||||
|
extensions.killAll(),
|
||||||
|
cluster.worker.disconnect()
|
||||||
|
]).catch(exitWorkerUngracefully);
|
||||||
}
|
}
|
||||||
|
|
||||||
function exitWorkerUngracefully(): void {
|
function exitWorkerUngracefully(): void {
|
||||||
|
|||||||
+6
-3
@@ -34,9 +34,12 @@ const SERVICE_ADDRESS = config.get("FS_INTERFACE");
|
|||||||
const SERVICE_PORT = config.get("FS_PORT");
|
const SERVICE_PORT = config.get("FS_PORT");
|
||||||
|
|
||||||
function exitWorkerGracefully(): void {
|
function exitWorkerGracefully(): void {
|
||||||
db.disconnect();
|
setTimeout(exitWorkerUngracefully, 5000).unref();
|
||||||
cache.disconnect();
|
Promise.all([
|
||||||
cluster.worker.disconnect();
|
db.disconnect(),
|
||||||
|
cache.disconnect(),
|
||||||
|
cluster.worker.disconnect()
|
||||||
|
]).catch(exitWorkerUngracefully);
|
||||||
}
|
}
|
||||||
|
|
||||||
function exitWorkerUngracefully(): void {
|
function exitWorkerUngracefully(): void {
|
||||||
|
|||||||
+7
-4
@@ -35,10 +35,13 @@ const SERVICE_ADDRESS = config.get("NBI_INTERFACE");
|
|||||||
const SERVICE_PORT = config.get("NBI_PORT");
|
const SERVICE_PORT = config.get("NBI_PORT");
|
||||||
|
|
||||||
function exitWorkerGracefully(): void {
|
function exitWorkerGracefully(): void {
|
||||||
db.disconnect();
|
setTimeout(exitWorkerUngracefully, 5000).unref();
|
||||||
cache.disconnect();
|
Promise.all([
|
||||||
extensions.killAll();
|
db.disconnect(),
|
||||||
cluster.worker.disconnect();
|
cache.disconnect(),
|
||||||
|
extensions.killAll(),
|
||||||
|
cluster.worker.disconnect()
|
||||||
|
]).catch(exitWorkerUngracefully);
|
||||||
}
|
}
|
||||||
|
|
||||||
function exitWorkerUngracefully(): void {
|
function exitWorkerUngracefully(): void {
|
||||||
|
|||||||
+8
-5
@@ -36,11 +36,14 @@ const SERVICE_ADDRESS = config.get("UI_INTERFACE");
|
|||||||
const SERVICE_PORT = config.get("UI_PORT");
|
const SERVICE_PORT = config.get("UI_PORT");
|
||||||
|
|
||||||
function exitWorkerGracefully(): void {
|
function exitWorkerGracefully(): void {
|
||||||
db.disconnect();
|
setTimeout(exitWorkerUngracefully, 5000).unref();
|
||||||
db2.disconnect();
|
Promise.all([
|
||||||
cache.disconnect();
|
db.disconnect(),
|
||||||
extensions.killAll();
|
db2.disconnect(),
|
||||||
cluster.worker.disconnect();
|
cache.disconnect(),
|
||||||
|
extensions.killAll(),
|
||||||
|
cluster.worker.disconnect()
|
||||||
|
]).catch(exitWorkerUngracefully);
|
||||||
}
|
}
|
||||||
|
|
||||||
function exitWorkerUngracefully(): void {
|
function exitWorkerUngracefully(): void {
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ Configure systemd
|
|||||||
User=genieacs
|
User=genieacs
|
||||||
EnvironmentFile=/opt/genieacs/genieacs.env
|
EnvironmentFile=/opt/genieacs/genieacs.env
|
||||||
ExecStart=/usr/bin/genieacs-cwmp
|
ExecStart=/usr/bin/genieacs-cwmp
|
||||||
KillMode=process
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
@@ -142,7 +141,6 @@ Configure systemd
|
|||||||
User=genieacs
|
User=genieacs
|
||||||
EnvironmentFile=/opt/genieacs/genieacs.env
|
EnvironmentFile=/opt/genieacs/genieacs.env
|
||||||
ExecStart=/usr/bin/genieacs-nbi
|
ExecStart=/usr/bin/genieacs-nbi
|
||||||
KillMode=process
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
@@ -165,7 +163,6 @@ Configure systemd
|
|||||||
User=genieacs
|
User=genieacs
|
||||||
EnvironmentFile=/opt/genieacs/genieacs.env
|
EnvironmentFile=/opt/genieacs/genieacs.env
|
||||||
ExecStart=/usr/bin/genieacs-fs
|
ExecStart=/usr/bin/genieacs-fs
|
||||||
KillMode=process
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
@@ -188,7 +185,6 @@ Configure systemd
|
|||||||
User=genieacs
|
User=genieacs
|
||||||
EnvironmentFile=/opt/genieacs/genieacs.env
|
EnvironmentFile=/opt/genieacs/genieacs.env
|
||||||
ExecStart=/usr/bin/genieacs-ui
|
ExecStart=/usr/bin/genieacs-ui
|
||||||
KillMode=process
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
|
|||||||
+4
-4
@@ -22,16 +22,16 @@ import * as config from "./config";
|
|||||||
|
|
||||||
const MAX_CACHE_TTL = +config.get("MAX_CACHE_TTL");
|
const MAX_CACHE_TTL = +config.get("MAX_CACHE_TTL");
|
||||||
|
|
||||||
let mongoClient: MongoClient;
|
let clientPromise: Promise<MongoClient>;
|
||||||
let mongoCollection: Collection;
|
let mongoCollection: Collection;
|
||||||
let mongoTimeOffset = 0;
|
let mongoTimeOffset = 0;
|
||||||
|
|
||||||
export async function connect(): Promise<void> {
|
export async function connect(): Promise<void> {
|
||||||
const MONGODB_CONNECTION_URL = "" + config.get("MONGODB_CONNECTION_URL");
|
const MONGODB_CONNECTION_URL = "" + config.get("MONGODB_CONNECTION_URL");
|
||||||
mongoClient = await MongoClient.connect(MONGODB_CONNECTION_URL, {
|
clientPromise = MongoClient.connect(MONGODB_CONNECTION_URL, {
|
||||||
useNewUrlParser: true
|
useNewUrlParser: true
|
||||||
});
|
});
|
||||||
const db = mongoClient.db();
|
const db = (await clientPromise).db();
|
||||||
mongoCollection = db.collection("cache");
|
mongoCollection = db.collection("cache");
|
||||||
await mongoCollection.createIndex({ expire: 1 }, { expireAfterSeconds: 0 });
|
await mongoCollection.createIndex({ expire: 1 }, { expireAfterSeconds: 0 });
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
@@ -40,7 +40,7 @@ export async function connect(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function disconnect(): Promise<void> {
|
export async function disconnect(): Promise<void> {
|
||||||
if (mongoClient) await mongoClient.close();
|
if (clientPromise) await (await clientPromise).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function get(key): Promise<any> {
|
export async function get(key): Promise<any> {
|
||||||
|
|||||||
+21
-8
@@ -22,7 +22,7 @@ import { cpus } from "os";
|
|||||||
import * as logger from "./logger";
|
import * as logger from "./logger";
|
||||||
|
|
||||||
let respawnTimestamp = 0;
|
let respawnTimestamp = 0;
|
||||||
let tooManyCrashesTimestamp = 0;
|
let crashes: number[] = [];
|
||||||
|
|
||||||
function fork(): cluster.Worker {
|
function fork(): cluster.Worker {
|
||||||
const w = cluster.fork();
|
const w = cluster.fork();
|
||||||
@@ -51,14 +51,21 @@ function restartWorker(worker, code, signal): void {
|
|||||||
logger.error(msg);
|
logger.error(msg);
|
||||||
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
respawnTimestamp = Math.max(now, respawnTimestamp + 2000);
|
crashes.push(now);
|
||||||
if (respawnTimestamp === now) {
|
|
||||||
tooManyCrashesTimestamp = now;
|
|
||||||
fork();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now - tooManyCrashesTimestamp > 60000) {
|
let min1 = 0,
|
||||||
|
min2 = 0,
|
||||||
|
min3 = 0;
|
||||||
|
|
||||||
|
crashes = crashes.filter(n => {
|
||||||
|
if (n > now - 60000) ++min1;
|
||||||
|
else if (n > now - 120000) ++min2;
|
||||||
|
else if (n > now - 180000) ++min3;
|
||||||
|
else return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (min1 > 5 && min2 > 5 && min3 > 5) {
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
cluster.removeListener("exit", restartWorker);
|
cluster.removeListener("exit", restartWorker);
|
||||||
for (const pid in cluster.workers) cluster.workers[pid].kill();
|
for (const pid in cluster.workers) cluster.workers[pid].kill();
|
||||||
@@ -70,6 +77,12 @@ function restartWorker(worker, code, signal): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
respawnTimestamp = Math.max(now, respawnTimestamp + 2000);
|
||||||
|
if (respawnTimestamp === now) {
|
||||||
|
fork();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (process.exitCode) return;
|
if (process.exitCode) return;
|
||||||
fork();
|
fork();
|
||||||
|
|||||||
@@ -44,13 +44,15 @@ export let tasksCollection: Collection,
|
|||||||
usersCollection: Collection,
|
usersCollection: Collection,
|
||||||
configCollection: Collection;
|
configCollection: Collection;
|
||||||
|
|
||||||
|
let clientPromise: Promise<MongoClient>;
|
||||||
export let client: MongoClient;
|
export let client: MongoClient;
|
||||||
|
|
||||||
export async function connect(): Promise<void> {
|
export async function connect(): Promise<void> {
|
||||||
client = await MongoClient.connect("" + get("MONGODB_CONNECTION_URL"), {
|
clientPromise = MongoClient.connect("" + get("MONGODB_CONNECTION_URL"), {
|
||||||
useNewUrlParser: true
|
useNewUrlParser: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
client = await clientPromise;
|
||||||
const db = client.db();
|
const db = client.db();
|
||||||
|
|
||||||
tasksCollection = db.collection("tasks");
|
tasksCollection = db.collection("tasks");
|
||||||
@@ -70,7 +72,7 @@ export async function connect(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function disconnect(): Promise<void> {
|
export async function disconnect(): Promise<void> {
|
||||||
if (client) await client.close();
|
if (clientPromise) await (await clientPromise).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimize projection by removing overlaps
|
// Optimize projection by removing overlaps
|
||||||
|
|||||||
+6
-10
@@ -26,7 +26,7 @@ import { QueryOptions } from "../types";
|
|||||||
|
|
||||||
const CACHE_TTL = 300000;
|
const CACHE_TTL = 300000;
|
||||||
|
|
||||||
let _clientPromise = null;
|
let clientPromise: Promise<MongoClient>;
|
||||||
|
|
||||||
const RESOURCE_COLLECTION = {
|
const RESOURCE_COLLECTION = {
|
||||||
files: "fs.files"
|
files: "fs.files"
|
||||||
@@ -40,8 +40,8 @@ function ensureIndexes(client): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getClient(): Promise<MongoClient> {
|
function getClient(): Promise<MongoClient> {
|
||||||
if (!_clientPromise) {
|
if (!clientPromise) {
|
||||||
_clientPromise = new Promise((resolve, reject) => {
|
clientPromise = new Promise((resolve, reject) => {
|
||||||
const CONNECTION_URL = "" + config.get("MONGODB_CONNECTION_URL");
|
const CONNECTION_URL = "" + config.get("MONGODB_CONNECTION_URL");
|
||||||
MongoClient.connect(
|
MongoClient.connect(
|
||||||
CONNECTION_URL,
|
CONNECTION_URL,
|
||||||
@@ -55,7 +55,7 @@ function getClient(): Promise<MongoClient> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return _clientPromise;
|
return clientPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cache<T>(key, valueGetter: () => Promise<T>, ttl): Promise<T> {
|
export function cache<T>(key, valueGetter: () => Promise<T>, ttl): Promise<T> {
|
||||||
@@ -405,10 +405,6 @@ export function deleteTask(id): Promise<void> {
|
|||||||
return deleteResource("tasks", id);
|
return deleteResource("tasks", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function disconnect(): void {
|
export async function disconnect(): Promise<void> {
|
||||||
if (_clientPromise) {
|
if (clientPromise) await (await clientPromise).close();
|
||||||
_clientPromise.then(client => {
|
|
||||||
client.close();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user