#!/usr/bin/env node /* Copyright (c) 2020, 2023, The Unified Company. This code is part of Unify. This program is free software; you can redistribute it and/or modify it under the terms of the ESA Software Community License - Strong Copyleft LICENSE, as published by the ESA. See the ESA Software Community License - Strong Copyleft LICENSE, for more details. https://unifyjs.org */ import fs from 'fs'; import path from 'path'; import cluster from 'cluster'; import os from 'os'; //import express from 'express'; import https from 'https'; import util from 'util'; import serverManager from './serverManager.js'; import applicationManager from './applicationManager.js'; import tools from '../unify/tools.js'; import moduleLoader from '../server/moduleLoader.js'; //import syncClient from '../sync/syncClient.js'; import user from '../cache/server/user/user.js'; import sqlite3 from '../node_modules/better-sqlite3/lib/index.js'; import fileList from '../configs/files.js'; import database from '../server/database.js'; import serverOptions from '../configs/config.js'; import colors from '../unify/consoleColors.js'; //import objectSizeof from "object-sizeof"; //import cacheManager from './scripts/cacheManager.js'; class unifyServer{ workers = new Array(); defineGlobals( clusterID ) { if( clusterID ){ global.clusterID = cluster.worker.id; } global.maxSocketBufferSize = 3000; global.mode = serverOptions.mode; global.socketPort = serverOptions.socketPort; global.ssl = serverOptions.ssl; global.useSyncServer = serverOptions.useSyncServer; global.os = tools.CamelCase( serverOptions.os ); global.device = tools.CamelCase( serverOptions.device ); global.tint = tools.CamelCase( serverOptions.tint ); global.database = database; global.path = path; global.user = user; global.util = util; global.sockets = new Array(); global.path = path; //global.objectSizeof = objectSizeof; if( !global.__dirname ) { global.__dirname = path.resolve(); } if( !global.extendMap ) { global.extendMap = new Array(); } if( serverOptions.useSyncServer ) { global.syncClient = new syncClient(); global.syncClient.clusterClientID = serverOptions.syncClientID; global.syncClient.syncServerAddress = serverOptions.syncServerAddress; } } createServer() { var server = new serverManager(); if( process.platform != "android" ) { server.port = serverOptions.port; server.ssl = serverOptions.ssl; server.mode = serverOptions.mode; server.serverAddress = serverOptions.serverAddress; //server.createExpressApp(); server.setupServer(); server.createHttpsServer(); server.createListener(); } return server.httpsServer; } createProcessListeners() { process.on("SIGTERM", (signal) => { console.log(`Process ${process.pid} received a SIGTERM signal`); if( global.syncClient ) { global.syncClient.emptyTable(); } process.exit(0); }); process.on("SIGINT", (signal) => { console.log(`Process ${process.pid} has been interrupted`); if( global.useSyncServer && global.syncClient ) { global.syncClient.emptyTable(); } process.exit(0); }); process.on('uncaughtException', function (err) { console.error( err ); }); } logServer( serverOptions ) { if( global.clusterID == 1 ) { if( serverOptions.ssl ) { console.log( "\nHttps WebServer started on port: 443" ); } else { console.log( "\nHttps WebServer started on port: ", serverOptions.port ); } } } async start( clusterID ) { this.defineGlobals( clusterID ); this.createProcessListeners(); var httpsServer = this.createServer(); var applications = new applicationManager(); applications.defaultSocketPort = serverOptions.socketPort; applications.httpsServer = httpsServer; await applications.runApplications( fileList ); //files.applications this.logServer( serverOptions ); } async processFiles() { var numCPUS = os.cpus().length; console.log("cpu cores detected: ", os.cpus().length ); if( serverOptions.maxClusters ) { console.log( "but max number of clusters set to: ", serverOptions.maxClusters ); var numberOfClusters = serverOptions.maxClusters; } else { console.log( "maxClusters is not set." ); var numberOfClusters = numCPUS; } console.log("Sync client loaded"); console.log("Loading ", numberOfClusters, "Cluster(s)."); console.log(""); console.log("platform detected: ", process.platform); if( process.platform == "android" ) { this.start( 0 ); } else { for (var i = 0; i < numberOfClusters; i++) { this.spawnCluster(); } } } spawnCluster() { var newCluster = cluster.fork(); this.workers.push( newCluster ); } setupClusters() { if( cluster.isMaster ) { var that = this; cluster.on("disconnect", function( worker ) { console.log("Cluster disconnected, start new cluster."); that.spawnCluster(); }); this.processFiles(); } else { console.log( "starting cluster: ", cluster.worker.id ); this.start( cluster.worker.id ); } } } //var cache = new cacheManager(); //await cache.start(); var server = new unifyServer(); server.setupClusters(); export default {};