diff --git a/backend/services/youtube-scheduler.js b/backend/services/youtube-scheduler.js index 37a6927..1978a52 100644 --- a/backend/services/youtube-scheduler.js +++ b/backend/services/youtube-scheduler.js @@ -58,15 +58,48 @@ async function syncBotStatuses() { const [bots] = await pool.query("SELECT id, status FROM bots"); for (const bot of bots) { - const isRunningInMemory = schedulers.has(bot.id); + const botId = parseInt(bot.id); + const isRunningInMemory = schedulers.has(botId); const isRunningInDB = bot.status === "running"; - // 메모리에 없는데 DB가 running이면 → 서버 크래시 등으로 불일치, DB를 stopped로 업데이트 + // 메모리에 없는데 DB가 running이면 → 서버 크래시 등으로 불일치 + // 이 경우 DB를 stopped로 변경하는 대신, 메모리에 봇을 다시 등록 if (!isRunningInMemory && isRunningInDB) { - await pool.query("UPDATE bots SET status = 'stopped' WHERE id = ?", [ - bot.id, - ]); - console.log(`[Scheduler] Bot ${bot.id} 상태 동기화: stopped`); + console.log(`[Scheduler] Bot ${botId} 메모리에 없음, 재등록 시도...`); + try { + const [botInfo] = await pool.query( + "SELECT check_interval, cron_expression FROM bots WHERE id = ?", + [botId] + ); + if (botInfo.length > 0) { + const { check_interval, cron_expression } = botInfo[0]; + // 직접 registerBot 함수 호출 (import 순환 방지를 위해 내부 로직 사용) + const expression = + cron_expression || `1-59/${check_interval} * * * *`; + const task = cron.schedule(expression, async () => { + console.log(`[Bot ${botId}] 동기화 시작...`); + try { + const result = await syncNewVideos(botId); + console.log( + `[Bot ${botId}] 동기화 완료: ${result.addedCount}개 추가` + ); + } catch (error) { + console.error(`[Bot ${botId}] 동기화 오류:`, error.message); + } + }); + schedulers.set(botId, task); + console.log( + `[Scheduler] Bot ${botId} 재등록 완료 (cron: ${expression})` + ); + } + } catch (error) { + console.error(`[Scheduler] Bot ${botId} 재등록 오류:`, error.message); + // 재등록 실패 시에만 stopped로 변경 + await pool.query("UPDATE bots SET status = 'stopped' WHERE id = ?", [ + botId, + ]); + console.log(`[Scheduler] Bot ${botId} 상태 동기화: stopped`); + } } } } catch (error) {