From 1419114d1e4f168aa574126197c63fe8c6791f58 Mon Sep 17 00:00:00 2001 From: bangdk Date: Tue, 19 Nov 2024 06:45:12 +0900 Subject: [PATCH] auto commit --- docker-compose.db.yml | 22 ++++++++++----------- fems-realtime-api/src/app.js | 38 ++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/docker-compose.db.yml b/docker-compose.db.yml index 413590f..77f4ec3 100644 --- a/docker-compose.db.yml +++ b/docker-compose.db.yml @@ -66,11 +66,11 @@ services: - ./fems-timescaledb/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro - ./fems-timescaledb/init-scripts:/docker-entrypoint-initdb.d/:ro command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"] - # healthcheck: - # test: - # ["CMD-SHELL", "pg_isready -U ${TIMESCALEDB_USER} -d ${TIMESCALEDB_DB}"] - networks: - - internal + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 fems-redis: image: redis:alpine @@ -86,15 +86,15 @@ services: - ./backups/redis:/backups environment: - NODE_ENV=${NODE_ENV:-development} - - REDIS_PASSWORD=${NODE_ENV:-development:-REDIS_PASSWORD} + - REDIS_PASSWORD=${REDIS_PASSWORD} depends_on: - fems-postgres - fems-timescaledb - # healthcheck: - # test: ["CMD", "redis-cli", "ping"] - # interval: 30s - # timeout: 10s - # retries: 3 + healthcheck: + test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] + interval: 10s + timeout: 5s + retries: 3 # fems-mqtt: # build: diff --git a/fems-realtime-api/src/app.js b/fems-realtime-api/src/app.js index e8af1df..fad85b4 100644 --- a/fems-realtime-api/src/app.js +++ b/fems-realtime-api/src/app.js @@ -6,12 +6,42 @@ const MainBackendService = require("./services/mainBackend.service"); const MQTTService = require("./services/mqtt.service"); const SensorDataModel = require("./models/SensorData"); const createDataController = require("./controllers/data.controller"); -// 다른 서비스나 컨트롤러 파일들 const logger = require("./config/logger"); const config = require("./config/config"); +const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + +async function waitForServices() { + const maxRetries = 30; + let retries = 0; + while (retries < maxRetries) { + try { + const pool = new Pool(config.timescaledb); + await pool.query("SELECT 1"); + await pool.end(); + const redis = new Redis(config.redis); + await redis.ping(); + await redis.quit(); + logger.info("Successfully connected to all services"); + return; + } catch (error) { + retries++; + logger.warn( + `Failed to connect to services, attempt ${retries}/${maxRetries}` + ); + await sleep(2000); + } + } + throw new Error("Failed to connect to required services"); +} + async function bootstrap() { + let mqttService = null; + try { + // 서비스 연결 대기 + await waitForServices(); + // 데이터베이스 연결 const pool = new Pool(config.timescaledb); const redis = new Redis(config.redis); @@ -27,7 +57,7 @@ async function bootstrap() { config.mainBackend.adminApiKey ); - const mqttService = new MQTTService( + mqttService = new MQTTService( mainBackend, sensorData, redis, @@ -43,6 +73,7 @@ async function bootstrap() { // 서비스 인스턴스를 app.locals에 저장 app.locals.mainBackend = mainBackend; + app.locals.mqttService = mqttService; // 라우터 설정 app.use("/api/v1/data", createDataController(pool, redis)); @@ -54,6 +85,9 @@ async function bootstrap() { }); } catch (error) { logger.error("Failed to start server:", error); + if (mqttService) { + await mqttService.disconnect(); + } process.exit(1); } }