121 lines
3.8 KiB
TypeScript
Executable File
121 lines
3.8 KiB
TypeScript
Executable File
import { buildShared } from "@/config/services.shared.js";
|
|
import { buildApi } from "@/config/services.api.js";
|
|
import { buildWorker } from "@/config/services.worker.js";
|
|
|
|
import { initializeControllers } from "./config/controllers.js";
|
|
import { createApp } from "./app.js";
|
|
import { initShutdownListener } from "@/shutdown.js";
|
|
import { validateEnv } from "@/config/envValidation.js";
|
|
import { fileURLToPath } from "url";
|
|
import path from "path";
|
|
import fs from "fs";
|
|
|
|
import Logger, { ILogger } from "@/utils/logger.js";
|
|
import { SettingsService } from "@/domain/app-settings/app-settings.service.js";
|
|
import { JobScheduler } from "@/worker/worker.job-scheduler.js";
|
|
import { IJobScheduler } from "@/worker/worker.interface.js";
|
|
import { HealthServer, IHealthServer } from "@/worker/worker.health-server.js";
|
|
const SERVICE_NAME = "Server";
|
|
let logger: ILogger;
|
|
|
|
const startApp = async () => {
|
|
// ***********************
|
|
// Basic setup
|
|
// ***********************
|
|
|
|
logger = new Logger();
|
|
const env = validateEnv(logger);
|
|
logger.setLogLevel(env.LOG_LEVEL);
|
|
const settingsService = new SettingsService(env);
|
|
const envSettings = settingsService.getSettings();
|
|
const { queueMode, queuePrimaryProcesses } = envSettings;
|
|
|
|
logger.info({
|
|
message: `Queue mode: ${queueMode}`,
|
|
service: SERVICE_NAME,
|
|
method: "startApp",
|
|
});
|
|
|
|
logger.info({
|
|
message: `Process jobs: ${queueMode === "worker" ? true : queuePrimaryProcesses}`,
|
|
service: SERVICE_NAME,
|
|
method: "startApp",
|
|
});
|
|
|
|
// ***********************
|
|
// Build shared services
|
|
// ***********************
|
|
const shared = await buildShared({ logger, envSettings, settingsService });
|
|
|
|
// ***********************
|
|
// Worker node path, don't need API
|
|
// ***********************
|
|
if (queueMode === "worker") {
|
|
const { worker } = await buildWorker(shared, envSettings);
|
|
const healthServer = new HealthServer(logger, env.HEALTH_PORT, worker);
|
|
await healthServer.listen();
|
|
logger.info({ message: "Worker instance started. API will not be started", service: SERVICE_NAME });
|
|
initShutdownListener(null, { worker, db: shared.db, logger, healthServer });
|
|
return;
|
|
}
|
|
|
|
// ***********************
|
|
// Primary node path
|
|
// ***********************
|
|
let scheduler: IJobScheduler;
|
|
let healthServer: IHealthServer | undefined;
|
|
|
|
// ***********************
|
|
//Primary node processes jobs, need full worker
|
|
// ***********************
|
|
if (queuePrimaryProcesses === true) {
|
|
const { worker } = await buildWorker(shared, envSettings);
|
|
healthServer = new HealthServer(logger, env.HEALTH_PORT, worker);
|
|
await healthServer.listen();
|
|
scheduler = worker;
|
|
}
|
|
// ***********************
|
|
// Primary node does not process jobs, only need scheduler
|
|
// ***********************
|
|
else {
|
|
scheduler = new JobScheduler(shared.jobsRepository, shared.queueWorkersRepository, shared.monitorsRepository, queueMode, logger, shared.workerId);
|
|
await scheduler.init(); // register in the queue_workers registry + reconcile (seed the jobs collection)
|
|
}
|
|
|
|
const services = buildApi(shared, scheduler);
|
|
|
|
// ***********************
|
|
// FE assets always needed for primary node
|
|
// ***********************
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
const openApiSpec = JSON.parse(fs.readFileSync(path.join(__dirname, "../openapi.json"), "utf8"));
|
|
const frontendPath = path.join(__dirname, "..", "public");
|
|
|
|
const controllers = initializeControllers(services);
|
|
|
|
const app = createApp({
|
|
apiServices: services,
|
|
controllers,
|
|
envSettings,
|
|
frontendPath,
|
|
openApiSpec,
|
|
});
|
|
const server = app.listen(env.PORT, () => {
|
|
logger.info({ message: `Server started on port:${env.PORT}` });
|
|
});
|
|
|
|
initShutdownListener(server, { ...services, healthServer });
|
|
};
|
|
|
|
startApp().catch((error) => {
|
|
logger.error({
|
|
message: error.message,
|
|
service: SERVICE_NAME,
|
|
method: "startApp",
|
|
stack: error.stack,
|
|
});
|
|
process.exit(1);
|
|
});
|