diff options
author | Bob Zeleznik <zzzman@gmail.com> | 2019-12-08 22:32:31 -0500 |
---|---|---|
committer | Bob Zeleznik <zzzman@gmail.com> | 2019-12-08 22:32:31 -0500 |
commit | cfaf02757f5aebd2ccce0bbef8b6f5e232932693 (patch) | |
tree | 021efc9779dc329e4e9ba94ac74eb6ef7e9dcb20 | |
parent | 6c28c3f00e5072b75a5d38da49a234cf347c6605 (diff) | |
parent | c3e0c3e7faf374a0d1b75c77d4f40abd7aec3a1f (diff) |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-rw-r--r-- | package.json | 3 | ||||
-rw-r--r-- | src/server/ActionUtilities.ts | 4 | ||||
-rw-r--r-- | src/server/ApiManagers/SearchManager.ts | 41 | ||||
-rw-r--r-- | src/server/ApiManagers/UtilManager.ts | 10 | ||||
-rw-r--r-- | src/server/Initialization.ts | 8 | ||||
-rw-r--r-- | src/server/Websocket/Websocket.ts | 11 | ||||
-rw-r--r-- | src/server/database.ts | 4 | ||||
-rw-r--r-- | src/server/index.ts | 43 |
8 files changed, 54 insertions, 70 deletions
diff --git a/package.json b/package.json index 32344aad4..1f0dd8d65 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "", "main": "index.js", "scripts": { + "start-release": "cross-env RELEASE=true NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev -- src/server/index.ts", "start": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev -- src/server/index.ts", "debug": "cross-env NODE_OPTIONS=--max_old_space_size=8192 ts-node-dev --inspect -- src/server/index.ts", "build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 webpack --env production", @@ -229,4 +230,4 @@ "xoauth2": "^1.2.0", "youtube": "^0.1.0" } -} +}
\ No newline at end of file diff --git a/src/server/ActionUtilities.ts b/src/server/ActionUtilities.ts index 1ebeab203..94008e171 100644 --- a/src/server/ActionUtilities.ts +++ b/src/server/ActionUtilities.ts @@ -73,7 +73,3 @@ export async function Prune(rootDirectory: string): Promise<boolean> { } export const Destroy = (mediaPath: string) => new Promise<boolean>(resolve => fs.unlink(mediaPath, error => resolve(error === null))); - -export function addBeforeExitHandler(handler: NodeJS.BeforeExitListener) { - // process.on("beforeExit", handler); -} diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts index 0e794fed6..ccd0896bd 100644 --- a/src/server/ApiManagers/SearchManager.ts +++ b/src/server/ApiManagers/SearchManager.ts @@ -4,9 +4,10 @@ import { Search } from "../Search"; const findInFiles = require('find-in-files'); import * as path from 'path'; import { pathToDirectory, Directory } from "./UploadManager"; -import { command_line, addBeforeExitHandler } from "../ActionUtilities"; +import { command_line } from "../ActionUtilities"; import request = require('request-promise'); -import { red, green, yellow, cyan } from "colors"; +import { red } from "colors"; +import RouteSubscriber from "../RouteSubscriber"; export class SearchManager extends ApiManager { @@ -14,14 +15,16 @@ export class SearchManager extends ApiManager { register({ method: Method.GET, - subscription: "/startSolr", - onValidation: async ({ res }) => res.send((await SolrManager.SetRunning(true)) ? "Successfully started Solr!" : "Uh oh! Check the console for the error that occurred while starting Solr") - }); - - register({ - method: Method.GET, - subscription: "/stopSolr", - onValidation: async ({ res }) => res.send((await SolrManager.SetRunning(false)) ? "Successfully stopped Solr!" : "Uh oh! Check the console for the error that occurred while stopping Solr") + subscription: new RouteSubscriber("solr").add("action"), + onValidation: async ({ req, res }) => { + const { action } = req.params; + if (["start", "stop"].includes(action)) { + const status = req.params.action === "start"; + const success = await SolrManager.SetRunning(status); + console.log(success ? `Successfully ${status ? "started" : "stopped"} Solr!` : `Uh oh! Check the console for the error that occurred while ${status ? "starting" : "stopping"} Solr`); + } + res.redirect("/home"); + } }); register({ @@ -65,30 +68,14 @@ export class SearchManager extends ApiManager { export namespace SolrManager { - export async function initializeSolr() { - console.log(cyan("\nInspecting Solr status...")); - try { - await request("http://localhost:8983"); - console.log(green('Solr already running\n')); - } catch (e) { - console.log(cyan('Initializing Solr...')); - await SolrManager.SetRunning(true); - } finally { - addBeforeExitHandler(async () => SolrManager.SetRunning(false)); - } - } - export async function SetRunning(status: boolean): Promise<boolean> { const args = status ? "start" : "stop -p 8983"; - console.log(`Solr management: trying to ${args}`); try { + console.log(`Solr management: trying to ${args}`); console.log(await command_line(`solr.cmd ${args}`, "../../solr-8.1.1/bin")); return true; } catch (e) { console.log(red(`Solr management error: unable to ${args}`)); - if (status) { - process.exit(0); - } return false; } } diff --git a/src/server/ApiManagers/UtilManager.ts b/src/server/ApiManagers/UtilManager.ts index 601a7d0d0..e959645e0 100644 --- a/src/server/ApiManagers/UtilManager.ts +++ b/src/server/ApiManagers/UtilManager.ts @@ -3,6 +3,7 @@ import { Method } from "../RouteManager"; import { exec } from 'child_process'; import { command_line } from "../ActionUtilities"; import RouteSubscriber from "../RouteSubscriber"; +import { red } from "colors"; export default class UtilManager extends ApiManager { @@ -11,7 +12,14 @@ export default class UtilManager extends ApiManager { register({ method: Method.GET, subscription: new RouteSubscriber("environment").add("key"), - onValidation: ({ req, res }) => res.send(process.env[req.params.key]) + onValidation: ({ req, res }) => { + const { key } = req.params; + const value = process.env[key]; + if (!value) { + console.log(red(`process.env.${key} is not defined.`)); + } + return res.send(value); + } }); register({ diff --git a/src/server/Initialization.ts b/src/server/Initialization.ts index ff2b64317..b58bc3e70 100644 --- a/src/server/Initialization.ts +++ b/src/server/Initialization.ts @@ -18,8 +18,8 @@ import * as whm from 'webpack-hot-middleware'; import * as fs from 'fs'; import * as request from 'request'; import RouteSubscriber from './RouteSubscriber'; -import { publicDirectory } from '.'; -import { logPort, addBeforeExitHandler } from './ActionUtilities'; +import { publicDirectory, ExitHandlers } from '.'; +import { logPort, } from './ActionUtilities'; import { timeMap } from './ApiManagers/UserManager'; import { blue, yellow } from 'colors'; @@ -31,6 +31,8 @@ export interface InitializationOptions { routeSetter: RouteSetter; } +export let disconnect: Function; + export default async function InitializeServer(options: InitializationOptions) { const { serverPort, routeSetter } = options; const app = buildWithMiddleware(express()); @@ -65,7 +67,7 @@ export default async function InitializeServer(options: InitializationOptions) { logPort("server", serverPort); console.log(); }); - addBeforeExitHandler(async () => { await new Promise<Error>(resolve => server.close(resolve)); }); + disconnect = async () => new Promise<Error>(resolve => server.close(resolve)); return isRelease; } diff --git a/src/server/Websocket/Websocket.ts b/src/server/Websocket/Websocket.ts index f65cc235c..5c0bb508b 100644 --- a/src/server/Websocket/Websocket.ts +++ b/src/server/Websocket/Websocket.ts @@ -7,15 +7,16 @@ import { Search } from "../Search"; import * as io from 'socket.io'; import YoutubeApi from "../apis/youtube/youtubeApiSample"; import { GoogleCredentialsLoader } from "../credentials/CredentialsLoader"; -import { logPort, addBeforeExitHandler } from "../ActionUtilities"; +import { logPort } from "../ActionUtilities"; import { timeMap } from "../ApiManagers/UserManager"; import { green } from "colors"; -import { ExitHandlers } from ".."; +import { SolrManager } from "../ApiManagers/SearchManager"; export namespace WebSocket { const clients: { [key: string]: Client } = {}; export const socketMap = new Map<SocketIO.Socket, string>(); + export let disconnect: Function; export async function start(serverPort: number, isRelease: boolean) { await preliminaryFunctions(); @@ -54,8 +55,12 @@ export namespace WebSocket { Utils.AddServerHandlerCallback(socket, MessageStore.GetRefField, GetRefField); Utils.AddServerHandlerCallback(socket, MessageStore.GetRefFields, GetRefFields); - ExitHandlers.push(() => socket.broadcast.emit("connection_terminated", Date.now())); + disconnect = () => { + socket.broadcast.emit("connection_terminated", Date.now()); + socket.disconnect(true); + }; }); + endpoint.listen(socketPort); logPort("websocket", socketPort); } diff --git a/src/server/database.ts b/src/server/database.ts index 5bdf1fc45..6e0771c11 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -6,10 +6,10 @@ import { DashUploadUtils } from './DashUploadUtils'; import { Credentials } from 'google-auth-library'; import { GoogleApiServerUtils } from './apis/google/GoogleApiServerUtils'; import * as mongoose from 'mongoose'; -import { addBeforeExitHandler } from './ActionUtilities'; export namespace Database { + export let disconnect: Function; const schema = 'Dash'; const port = 27017; export const url = `mongodb://localhost:${port}/${schema}`; @@ -25,7 +25,7 @@ export namespace Database { export async function tryInitializeConnection() { try { const { connection } = mongoose; - addBeforeExitHandler(async () => { await new Promise<any>(resolve => connection.close(resolve)); }); + disconnect = async () => new Promise<any>(resolve => connection.close(resolve)); if (connection.readyState === ConnectionStates.disconnected) { await new Promise<void>((resolve, reject) => { connection.on('error', reject); diff --git a/src/server/index.ts b/src/server/index.ts index 42b4f7ff2..6099af83c 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -22,6 +22,7 @@ import { log_execution } from "./ActionUtilities"; import GeneralGoogleManager from "./ApiManagers/GeneralGoogleManager"; import GooglePhotosManager from "./ApiManagers/GooglePhotosManager"; import { yellow } from "colors"; +import { disconnect } from "../server/Initialization"; export const publicDirectory = path.resolve(__dirname, "public"); export const filesDirectory = path.resolve(publicDirectory, "files"); @@ -34,35 +35,6 @@ export const ExitHandlers = new Array<() => void>(); * before clients can access the server should be run or awaited here. */ async function preliminaryFunctions() { - process.on('SIGINT', () => { - const { stdin, stdout, stderr } = process; - stdin.resume(); - stdout.resume(); - stderr.resume(); - ExitHandlers.forEach(handler => handler()); - console.log("Okay, now we're done..."); - // process.exit(0); - }); - - (process as any).on('cleanup', () => { - console.log("CLEANING UP!"); - }); - - process.on('exit', function () { - (process.emit as Function)('cleanup'); - }); - - //catch uncaught exceptions, trace, then exit normally - process.on('uncaughtException', function (e) { - console.log('Uncaught Exception...'); - process.exit(99); - }); - process.on('unhandledRejection', function (e) { - console.log('Unhandled Rejection...'); - process.exit(99); - }); - - await SolrManager.initializeSolr(); await GoogleCredentialsLoader.loadCredentials(); GoogleApiServerUtils.processProjectCredentials(); await DashUploadUtils.buildFileDirectories(); @@ -114,6 +86,19 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }: onValidation: ({ res }) => res.send(true) }); + addSupervisedRoute({ + method: Method.GET, + subscription: "/shutdown", + onValidation: async ({ res }) => { + WebSocket.disconnect(); + await disconnect(); + await Database.disconnect(); + SolrManager.SetRunning(false); + res.send("Server successfully shut down."); + process.exit(0); + } + }); + const serve: OnUnauthenticated = ({ req, res }) => { const detector = new mobileDetect(req.headers['user-agent'] || ""); const filename = detector.mobile() !== null ? 'mobile/image.html' : 'index.html'; |