Fix process shutdown issues

This commit is contained in:
Zaid Abdulla committed 2019-09-23 16:03:08 -07:00
1 parent 4bcee572f1
commit ed0aa8ae7a
9 files changed
+63 -44

No files matched your search

+7 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 {
-4
View File
@@ -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
View File
@@ -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
View File
@@ -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();
+4 -2
View File
@@ -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
View File
@@ -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();
});
}
} }