This commit is contained in:
lunaticbum 2026-03-13 16:46:33 +09:00
parent fcd6b5e800
commit 57abcbf8f8
2 changed files with 27 additions and 5 deletions

View File

@ -502,10 +502,11 @@ object AutoTradingManager {
println("🌙 [System] 업무 종료 및 자원 정리 시작...") println("🌙 [System] 업무 종료 및 자원 정리 시작...")
SystemSleepPreventer.sleepDisplay() // 모니터 끄기 SystemSleepPreventer.sleepDisplay() // 모니터 끄기
KisWebSocketManager.disconnect() KisWebSocketManager.disconnect()
//isSystemReadyToday = false BrowserManager.closeIfIdle(0) // 즉시 닫기
if (LlamaServerManager.stopAll()) { if (LlamaServerManager.stopAll()) {
isSystemCleanedUpToday = true isSystemCleanedUpToday = true
} }
} }
println("✅ [System] 오늘의 모든 정리가 완료되었습니다.") println("✅ [System] 오늘의 모든 정리가 완료되었습니다.")
} catch (e: Exception) { } catch (e: Exception) {
@ -637,6 +638,7 @@ object AutoTradingManager {
private suspend fun waitForNextCycle(minutes: Double) { private suspend fun waitForNextCycle(minutes: Double) {
println("💤 대기 모드 진입... $minutes") println("💤 대기 모드 진입... $minutes")
val endWait = System.currentTimeMillis() + (minutes * 60 * 1000L) val endWait = System.currentTimeMillis() + (minutes * 60 * 1000L)
BrowserManager.closeIfIdle(0) // 즉시 닫기
while (System.currentTimeMillis() < endWait && isRunning()) { while (System.currentTimeMillis() < endWait && isRunning()) {
lastTickTime.set(System.currentTimeMillis()) // 대기 중에도 Watchdog에 생존 신고 lastTickTime.set(System.currentTimeMillis()) // 대기 중에도 Watchdog에 생존 신고
println("💤 대기 모드 상태 확인...") println("💤 대기 모드 상태 확인...")
@ -645,7 +647,6 @@ object AutoTradingManager {
} }
private suspend fun executeClosingLiquidation(tradeService: KisTradeService) { private suspend fun executeClosingLiquidation(tradeService: KisTradeService) {
val activeTrades = DatabaseFactory.findAllMonitoringTrades() val activeTrades = DatabaseFactory.findAllMonitoringTrades()
val balanceResult = tradeService.fetchIntegratedBalance().getOrNull() val balanceResult = tradeService.fetchIntegratedBalance().getOrNull()

View File

@ -1,5 +1,6 @@
package service package service
import com.microsoft.playwright.Browser
import com.microsoft.playwright.Playwright import com.microsoft.playwright.Playwright
import com.microsoft.playwright.BrowserType import com.microsoft.playwright.BrowserType
import com.microsoft.playwright.Page import com.microsoft.playwright.Page
@ -27,9 +28,9 @@ object BrowserManager {
private const val MAX_TOTAL_FAILURES = 3 private const val MAX_TOTAL_FAILURES = 3
private val mutex = Mutex() // 동시 접근 제어용 뮤텍스 private val mutex = Mutex() // 동시 접근 제어용 뮤텍스
suspend fun getBrowser(): com.microsoft.playwright.Browser { suspend fun getBrowser(): Browser {
return mutex.withLock { return mutex.withLock {
// 브라우저가 없거나 연결이 끊겼다면 새로 생성 lastAccessTime = System.currentTimeMillis() // 접근 시간 갱신
if (_browser == null || !_browser!!.isConnected) { if (_browser == null || !_browser!!.isConnected) {
startNewBrowser() startNewBrowser()
} }
@ -64,7 +65,9 @@ object BrowserManager {
} catch (e: Exception) { } catch (e: Exception) {
// 종료 에러 무시 // 종료 에러 무시
} finally { } finally {
startNewBrowser() if (util.MarketUtil.isKoreanMarketOpen()) {
startNewBrowser()
}
failCount = 0 failCount = 0
} }
} }
@ -81,6 +84,24 @@ object BrowserManager {
println("🚨 브라우저 엔진 시작 실패: ${e.message}") println("🚨 브라우저 엔진 시작 실패: ${e.message}")
} }
} }
private var lastAccessTime = System.currentTimeMillis()
// 대기 모드일 때 호출하여 메모리 해제
suspend fun closeIfIdle(idleTimeoutMs: Long = 60_000) {
mutex.withLock {
if (_browser != null && System.currentTimeMillis() - lastAccessTime > idleTimeoutMs) {
println("♻️ [SafeScraper] 장시간 대기로 브라우저 자원을 해제합니다.")
_browser?.close()
playwright?.close()
_browser = null
playwright = null
}
}
}
} }
object DynamicNewsScraper { object DynamicNewsScraper {