chore: restart web server when ports in config have changed #2100
							
								
								
									
										27
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/index.ts
									
									
									
									
									
								
							@ -12,12 +12,10 @@ import { logger } from "@/src/utils/logger";
 | 
			
		||||
logger.info("Starting up...");
 | 
			
		||||
 | 
			
		||||
// Proceed with normal startup: bring up config watcher service, validate config, connect to MongoDB, and finally start listening for HTTP.
 | 
			
		||||
import http from "http";
 | 
			
		||||
import https from "https";
 | 
			
		||||
import fs from "node:fs";
 | 
			
		||||
import { app } from "./app";
 | 
			
		||||
import mongoose from "mongoose";
 | 
			
		||||
import { JSONStringify } from "json-with-bigint";
 | 
			
		||||
import { startWebServer } from "./services/webService";
 | 
			
		||||
 | 
			
		||||
import { validateConfig } from "@/src/services/configWatcherService";
 | 
			
		||||
 | 
			
		||||
// Patch JSON.stringify to work flawlessly with Bigints.
 | 
			
		||||
@ -29,26 +27,7 @@ mongoose
 | 
			
		||||
    .connect(config.mongodbUrl)
 | 
			
		||||
    .then(() => {
 | 
			
		||||
        logger.info("Connected to MongoDB");
 | 
			
		||||
 | 
			
		||||
        const httpPort = config.httpPort || 80;
 | 
			
		||||
        const httpsPort = config.httpsPort || 443;
 | 
			
		||||
        const options = {
 | 
			
		||||
            key: fs.readFileSync("static/certs/key.pem"),
 | 
			
		||||
            cert: fs.readFileSync("static/certs/cert.pem")
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
        http.createServer(app).listen(httpPort, () => {
 | 
			
		||||
            logger.info("HTTP server started on port " + httpPort);
 | 
			
		||||
            // eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
            https.createServer(options, app).listen(httpsPort, () => {
 | 
			
		||||
                logger.info("HTTPS server started on port " + httpsPort);
 | 
			
		||||
 | 
			
		||||
                logger.info(
 | 
			
		||||
                    "Access the WebUI in your browser at http://localhost" + (httpPort == 80 ? "" : ":" + httpPort)
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        startWebServer();
 | 
			
		||||
    })
 | 
			
		||||
    .catch(error => {
 | 
			
		||||
        if (error instanceof Error) {
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@ import fs from "fs";
 | 
			
		||||
import fsPromises from "fs/promises";
 | 
			
		||||
import { logger } from "../utils/logger";
 | 
			
		||||
import { config, configPath, loadConfig } from "./configService";
 | 
			
		||||
import { getWebPorts, startWebServer, stopWebServer } from "./webService";
 | 
			
		||||
 | 
			
		||||
let amnesia = false;
 | 
			
		||||
fs.watchFile(configPath, () => {
 | 
			
		||||
@ -16,6 +17,12 @@ fs.watchFile(configPath, () => {
 | 
			
		||||
            process.exit(1);
 | 
			
		||||
        }
 | 
			
		||||
        validateConfig();
 | 
			
		||||
 | 
			
		||||
        const webPorts = getWebPorts();
 | 
			
		||||
        if (config.httpPort != webPorts.http || config.httpsPort != webPorts.https) {
 | 
			
		||||
            logger.info(`Restarting web server to apply port changes.`);
 | 
			
		||||
            void stopWebServer().then(startWebServer);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										65
									
								
								src/services/webService.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/services/webService.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
import http from "http";
 | 
			
		||||
import https from "https";
 | 
			
		||||
import fs from "node:fs";
 | 
			
		||||
import { config } from "./configService";
 | 
			
		||||
import { logger } from "../utils/logger";
 | 
			
		||||
import { app } from "../app";
 | 
			
		||||
import { AddressInfo } from "node:net";
 | 
			
		||||
 | 
			
		||||
let httpServer: http.Server | undefined;
 | 
			
		||||
let httpsServer: https.Server | undefined;
 | 
			
		||||
 | 
			
		||||
const tlsOptions = {
 | 
			
		||||
    key: fs.readFileSync("static/certs/key.pem"),
 | 
			
		||||
    cert: fs.readFileSync("static/certs/cert.pem")
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const startWebServer = (): void => {
 | 
			
		||||
    const httpPort = config.httpPort || 80;
 | 
			
		||||
    const httpsPort = config.httpsPort || 443;
 | 
			
		||||
 | 
			
		||||
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
    httpServer = http.createServer(app);
 | 
			
		||||
    httpServer.listen(httpPort, () => {
 | 
			
		||||
        logger.info("HTTP server started on port " + httpPort);
 | 
			
		||||
        // eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
        httpsServer = https.createServer(tlsOptions, app);
 | 
			
		||||
        httpsServer.listen(httpsPort, () => {
 | 
			
		||||
            logger.info("HTTPS server started on port " + httpsPort);
 | 
			
		||||
 | 
			
		||||
            logger.info(
 | 
			
		||||
                "Access the WebUI in your browser at http://localhost" + (httpPort == 80 ? "" : ":" + httpPort)
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getWebPorts = (): Record<"http" | "https", number | undefined> => {
 | 
			
		||||
    return {
 | 
			
		||||
        http: (httpServer?.address() as AddressInfo | undefined)?.port,
 | 
			
		||||
        https: (httpsServer?.address() as AddressInfo | undefined)?.port
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const stopWebServer = async (): Promise<void> => {
 | 
			
		||||
    const promises: Promise<void>[] = [];
 | 
			
		||||
    if (httpServer) {
 | 
			
		||||
        promises.push(
 | 
			
		||||
            new Promise(resolve => {
 | 
			
		||||
                httpServer!.close(() => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    if (httpsServer) {
 | 
			
		||||
        promises.push(
 | 
			
		||||
            new Promise(resolve => {
 | 
			
		||||
                httpsServer!.close(() => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    await Promise.all(promises);
 | 
			
		||||
};
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user