Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3cd1b5d5f | ||
|
|
51dcacc728 | ||
|
|
dc8a8e9b4c |
@@ -6,6 +6,14 @@
|
|||||||
|
|
||||||
## 2026-06-15
|
## 2026-06-15
|
||||||
|
|
||||||
|
### ♿ #301+#302 모달 접근성 + race condition + 필터 상태 동기화 (v0.1.14)
|
||||||
|
- 공통 훅 `frontend/src/lib/hooks/useModalA11y.ts` 신규 (useEscapeKey, useFocusTrap, useBodyScrollLock)
|
||||||
|
- BottomSheet/FilterSheet: role='dialog', aria-modal, aria-label/labelledby, ESC 닫기, focus trap
|
||||||
|
- RestaurantDetail: useEffect cancelled 플래그로 restaurant.id 변경 시 race condition 차단
|
||||||
|
- page.tsx: `exitSearchMode` 헬퍼 → 검색결과 모드에서 필터 변경 시 자동 검색 모드 해제 + 원본 재로드
|
||||||
|
- 후속 분리: #319 (BottomSheet 매직넘버/UX), #320 (필터 정밀도/접근성/테스트)
|
||||||
|
- Refs: #301 #302 (close)
|
||||||
|
|
||||||
### 🔧 #316 — backend resource request 재산정 + RollingUpdate 정책 복귀
|
### 🔧 #316 — backend resource request 재산정 + RollingUpdate 정책 복귀
|
||||||
- **변경 전**: cpu 500m/1, mem 768Mi/1536Mi, strategy maxSurge=0/maxUnavailable=1 (임시 패치)
|
- **변경 전**: cpu 500m/1, mem 768Mi/1536Mi, strategy maxSurge=0/maxUnavailable=1 (임시 패치)
|
||||||
- **변경 후**: cpu 300m/800m, mem 512Mi/1024Mi, strategy 25%/25% (기본 복귀)
|
- **변경 후**: cpu 300m/800m, mem 512Mi/1024Mi, strategy 25%/25% (기본 복귀)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.tasteby.service;
|
|||||||
import com.tasteby.domain.DaemonConfig;
|
import com.tasteby.domain.DaemonConfig;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -22,6 +23,9 @@ public class DaemonScheduler {
|
|||||||
private final PipelineService pipelineService;
|
private final PipelineService pipelineService;
|
||||||
private final CacheService cacheService;
|
private final CacheService cacheService;
|
||||||
|
|
||||||
|
@Value("${app.daemon.enabled:true}")
|
||||||
|
private boolean instanceEnabled;
|
||||||
|
|
||||||
public DaemonScheduler(DaemonConfigService daemonConfigService,
|
public DaemonScheduler(DaemonConfigService daemonConfigService,
|
||||||
YouTubeService youTubeService,
|
YouTubeService youTubeService,
|
||||||
PipelineService pipelineService,
|
PipelineService pipelineService,
|
||||||
@@ -34,6 +38,10 @@ public class DaemonScheduler {
|
|||||||
|
|
||||||
@Scheduled(fixedDelay = 30_000) // Check every 30 seconds
|
@Scheduled(fixedDelay = 30_000) // Check every 30 seconds
|
||||||
public void run() {
|
public void run() {
|
||||||
|
// 인스턴스 차원 차단(dev/prod 동일 DB 공유 환경에서 dev 쪽 동시 폴링 방지).
|
||||||
|
// dev .env: DAEMON_ENABLED=false → 이 인스턴스는 스케줄러 동작 안 함.
|
||||||
|
// prod: 미설정 → 기본 true.
|
||||||
|
if (!instanceEnabled) return;
|
||||||
try {
|
try {
|
||||||
var config = getConfig();
|
var config = getConfig();
|
||||||
if (config == null) return;
|
if (config == null) return;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ public class YouTubeService {
|
|||||||
String uploadsPlaylistId = "UU" + channelId.substring(2);
|
String uploadsPlaylistId = "UU" + channelId.substring(2);
|
||||||
List<Map<String, Object>> allVideos = new ArrayList<>();
|
List<Map<String, Object>> allVideos = new ArrayList<>();
|
||||||
String nextPage = null;
|
String nextPage = null;
|
||||||
|
boolean stopPaging = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
do {
|
do {
|
||||||
@@ -88,7 +89,7 @@ public class YouTubeService {
|
|||||||
// publishedAfter 필터: 이미 스캔한 영상 이후만
|
// publishedAfter 필터: 이미 스캔한 영상 이후만
|
||||||
if (publishedAfter != null && publishedAt.compareTo(publishedAfter) <= 0) {
|
if (publishedAfter != null && publishedAt.compareTo(publishedAfter) <= 0) {
|
||||||
// 업로드 재생목록은 최신순이므로 이전 날짜 만나면 중단
|
// 업로드 재생목록은 최신순이므로 이전 날짜 만나면 중단
|
||||||
nextPage = null;
|
stopPaging = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +106,9 @@ public class YouTubeService {
|
|||||||
}
|
}
|
||||||
allVideos.addAll(pageVideos);
|
allVideos.addAll(pageVideos);
|
||||||
|
|
||||||
if (nextPage != null || data.has("nextPageToken")) {
|
if (stopPaging) {
|
||||||
|
nextPage = null;
|
||||||
|
} else {
|
||||||
nextPage = data.has("nextPageToken") ? data.path("nextPageToken").asText() : null;
|
nextPage = data.has("nextPageToken") ? data.path("nextPageToken").asText() : null;
|
||||||
}
|
}
|
||||||
} while (nextPage != null);
|
} while (nextPage != null);
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ app:
|
|||||||
cache:
|
cache:
|
||||||
ttl-seconds: 600
|
ttl-seconds: 600
|
||||||
|
|
||||||
|
daemon:
|
||||||
|
# 인스턴스 차원 스케줄러 활성화. dev/prod가 같은 DB를 공유하므로
|
||||||
|
# dev .env에 DAEMON_ENABLED=false를 설정해 dev 폴링을 끄고 prod만 동작시킨다.
|
||||||
|
enabled: ${DAEMON_ENABLED:true}
|
||||||
|
|
||||||
mybatis:
|
mybatis:
|
||||||
mapper-locations: classpath:mybatis/mapper/*.xml
|
mapper-locations: classpath:mybatis/mapper/*.xml
|
||||||
config-location: classpath:mybatis/mybatis-config.xml
|
config-location: classpath:mybatis/mybatis-config.xml
|
||||||
|
|||||||
Reference in New Issue
Block a user