From 915f2be8aec7aab8533997cbabd14614c9575815 Mon Sep 17 00:00:00 2001 From: minij02 Date: Mon, 27 Jul 2026 00:54:54 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20Upstash=20=EC=9C=A0=ED=9C=B4=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=20=EC=82=AD=EC=A0=9C=20=EB=B0=A9=EC=A7=80=20?= =?UTF-8?q?=E2=80=94=20/health/redis=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20+=20=EC=A3=BC=EA=B0=84=20keepalive=20cron?= =?UTF-8?q?=20(#527)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GET /health/redis: redisClient.ping() 을 2s 타임아웃과 함께 실행 (실패 시 503) - .github/workflows/redis-keepalive.yml: 매주 월 12:00 KST 로 dev 엔드포인트 curl --- .github/workflows/redis-keepalive.yml | 13 +++++++++++++ src/index.ts | 18 +++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/redis-keepalive.yml diff --git a/.github/workflows/redis-keepalive.yml b/.github/workflows/redis-keepalive.yml new file mode 100644 index 0000000..3057916 --- /dev/null +++ b/.github/workflows/redis-keepalive.yml @@ -0,0 +1,13 @@ +name: redis-keepalive + +on: + schedule: + - cron: '0 3 * * 1' # 매주 월요일 03:00 UTC (12:00 KST) + workflow_dispatch: + +jobs: + ping: + runs-on: ubuntu-latest + steps: + - name: Ping dev Redis via /health/redis + run: curl -fsS -m 10 https://promptplace-dev.kro.kr/health/redis diff --git a/src/index.ts b/src/index.ts index 6b8ba55..5a6c4dd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ import { errorHandler } from "./middlewares/errorHandler"; import { visitorTracker } from "./middlewares/visitorTracker"; import "reflect-metadata"; import passport from "./config/passport"; +import redisClient from "./config/redis"; import swaggerUi from "swagger-ui-express"; import swaggerJsdoc from "swagger-jsdoc"; import { swaggerOptions } from "./docs/swagger/options"; @@ -210,7 +211,22 @@ app.use(errorHandler as ErrorRequestHandler); // 도커 헬스체크 라우터 app.get('/health', (req, res) => { - res.status(200).send('OK'); + res.status(200).send('OK'); +}); + +// ponytail: Upstash free 유휴 자동 삭제 방지용. 외부 cron 이 주기적으로 호출. +app.get('/health/redis', async (_req, res) => { + try { + const pong = await Promise.race([ + redisClient.ping(), + new Promise((_, reject) => + setTimeout(() => reject(new Error('timeout')), 2000), + ), + ]); + res.status(200).send(pong); + } catch { + res.status(503).send('REDIS_UNAVAILABLE'); + } }); app.use(morgan('dev')); // 사용자 요청 로그 출력 From d6e257a10bad02260d1a4c519799d96ee7d3ae05 Mon Sep 17 00:00:00 2001 From: minij02 Date: Mon, 27 Jul 2026 00:59:18 +0900 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20prod=20URL=20=EB=8F=84=20keepalive?= =?UTF-8?q?=20=EB=8C=80=EC=83=81=EC=97=90=20=EC=B6=94=EA=B0=80=20(#527)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/redis-keepalive.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/redis-keepalive.yml b/.github/workflows/redis-keepalive.yml index 3057916..5245821 100644 --- a/.github/workflows/redis-keepalive.yml +++ b/.github/workflows/redis-keepalive.yml @@ -11,3 +11,5 @@ jobs: steps: - name: Ping dev Redis via /health/redis run: curl -fsS -m 10 https://promptplace-dev.kro.kr/health/redis + - name: Ping prod Redis via /health/redis + run: curl -fsS -m 10 https://promptplace.kro.kr/health/redis