- 모든 모드(ANY/ALL/SEQUENTIAL)에서 동일 구역 재방문 시 개별 방문 단위로 분리
- PolygonHitDetail에 visitIndex 필드 추가 (구역별 방문 순번, 1-based)
- 진입/진출 시각을 JTS LineSegment.intersection() 기반 거리 비율 보간으로 산출
- SEQUENTIAL 모드: greedy chain 탐색, 유효 체인만 반환 (visitIndex=1 재설정)
- hitDetails 배열을 entryTimestamp 오름차순 정렬 (배열 인덱스 = 전체 방문 순서)
- Swagger 설명에 개별 방문 분리, 경계 보간 관련 내용 추가
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- POST /api/v2/tracks/vessels: DailyTrackCacheManager 캐시-DB 분리 조회
- 모든 V2 항적 엔드포인트에 ActiveQueryManager 공유 Semaphore 적용
- 포인트 버짓: 총 포인트 초과 시 비율 기반 균등 분배 간소화
- prod/prod-mpr/query 프로파일에 rest.v2.query 설정 추가
- 원격 DB 필요 테스트 @Disabled 처리, Maven Wrapper/gitattributes 정비
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
vessel.integration.datasource.table-name → vessel.integration.table-name으로 변경.
YAML 구조와 불일치하여 prod에서 기본값(signal.t_ship_integration_sub)이 사용되었고,
별도 DB(mdadb2 gis 스키마)에 signal 스키마가 없어 조회 실패하던 문제 해결.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
캐시 기반 인메모리 다중 폴리곤 영역 내 선박 탐색 API 구현.
JTS STRtree + PreparedGeometry로 고속 공간 검색, ANY/ALL/SEQUENTIAL 3가지 모드 지원.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- IntegrationVesselService에 전용 DataSource 자체 생성/관리 추가
- vessel.integration.datasource.* 설정으로 별도 DB 연결 가능
- @PostConstruct에서 경량 HikariDataSource 생성 (max 3, min 1)
- 미설정 시 queryDataSource 자동 폴백 (기존 동작 유지)
- prod: 별도 DB (mdadb2 gis.t_ship_integration_sub) → 전용 DataSource
- dev/prod-mpr: queryDB signal 스키마 → queryDataSource 폴백
- 기존 DataSourceConfig 4개 파일 수정 없이 프로파일 완벽 호환
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
문제: 캐시 경로에서 뷰포트 공간 필터를 이중 적용하여,
다른 날짜에서 뷰포트를 통과한 선박의 항적이 누락되는 버그
수정 내용:
- collectViewportVesselIds: 캐시된 날짜는 메모리에서 뷰포트 체크 (DB 커넥션 절약)
- processDailyStrategy: viewportVesselIds(2-pass 결과) 있으면 vessel ID 필터만 적용,
공간 필터 재적용 금지 → 전체 조회기간 항적 무결성 보장
- processQueryInChunks: 동일 패턴 적용
- StompTrackStreamingService: 캐시 경로에 filteredVessels 필터 적용
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- DailyTrackCacheManager: D-1~D-7 daily 테이블 데이터 인메모리 캐시
- @Async 비동기 워밍업 (서버 시작 차단 없음, 최근 우선 로드)
- 뷰포트 필터링, 다중 날짜 병합 조회, 하이브리드 쿼리 분리
- 메모리 한도 체크 (기본 5GB), 날짜별 즉시 활성화
- DailyTrackCacheProperties: enabled, retentionDays, maxMemoryGb 설정
- DailyAggregationJobConfig: 배치 완료 시 캐시 자동 갱신 리스너
- ChunkedTrackStreamingService: daily 전략에서 캐시 우선 조회 + DB 폴백
- StompTrackStreamingService: 동일 캐시 우선 패턴 적용
- WebSocketMonitoringController: GET /api/websocket/daily-cache 엔드포인트
- application-prod.yml: cache.daily-track 설정 추가
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 4: 설정 외부화 및 모니터링
- WebSocketProperties: websocket.* 설정을 @ConfigurationProperties로 바인딩
- query: 동시 제한, 세션 제한, 대기 큐 타임아웃
- transport: 인바운드/아웃바운드 채널 스레드풀, 메시지 크기
- backpressure: 버퍼 크기, 메시지 크기 제한
- WebSocketMonitoringController에 /api/websocket/load-control 엔드포인트 추가
- 글로벌 동시 쿼리 수, 대기 큐 현황
- 활성 쿼리 상세 (세션ID, 쿼리ID, 시작시간, 진행테이블, 청크수, 취소여부)
- 메모리 사용률
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 3: 백프레셔 고도화
- ChunkedTrackStreamingService:
- CompletableFuture+Thread.sleep(100ms) 추정 방식 제거
- 전송 완료 후 try-finally에서 즉시 버퍼 크기 감소 (정확한 추적)
- 정적 대기 → 버퍼 사용률(%) 기반 4단계 적응형 지연
- StompTrackStreamingService:
- 총 트랙 수 기반 정적 지연 제거
- BlockingQueue 사용률 + 데이터 크기 복합 적응형 지연으로 교체
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 2.2: 쿼리 관리 시스템 통합
- StompTrackController의 status callback에서 activeQueryManager.completeQuery() 제거
- 리소스 정리를 서비스(ChunkedTrack/StompTrack) finally 블록에서 일괄 처리
- 중복 completeQuery 호출 제거로 쿼리 생명주기 관리 단일화
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 2.1: 기존 TODO만 있던 cancelQuery()에 실제 취소 메커니즘 추가
- 쿼리별 AtomicBoolean 취소 플래그(queryCancelFlags) 관리
- streamChunkedTracks 시작 시 취소 플래그 등록, finally에서 정리
- 테이블 전략별 루프 진입 전 취소 확인
- isQueryCancelled()에 queryCancelFlags 통합 확인 추가
- cancelQuery() 호출 시 플래그 설정으로 진행 중인 스트리밍 중단
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 1.3: 무제한 스레드 생성 방지
- newCachedThreadPool → ThreadPoolExecutor(core:5, max:20, queue:100)
- CallerRunsPolicy 적용으로 큐 포화 시 자연 백프레셔
- 부하 시 무제한 스레드 생성으로 인한 OOM/컨텍스트 스위칭 오버헤드 방지
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 1.1 + 1.2: WebSocket 리플레이 요청 동시 부하 제어
- ActiveQueryManager에 Fair Semaphore 기반 글로벌 동시 쿼리 제한 추가 (기본 30개)
- @Async 스트리밍 메서드 내에서 슬롯 획득 (인바운드 채널 블로킹 방지)
- 쿼리 완료/실패/취소 시 finally 블록에서 반드시 리소스 반환
- 글로벌 Semaphore 슬롯 반환
- 세션별 쿼리 카운트 감소 (기존 누락 수정)
- ActiveQueryManager 쿼리 정리
- TrackQueryInterceptor 세션 제한값 외부 설정화 (@Value)
- application-prod.yml에 websocket.query 설정 추가
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- GisService: 하위 구간 미집계 감지 시 상위 테이블에서 보완 집계하는
계층적 폴백 로직 추가 (daily→hourly→5min)
- ChunkedTrackStreamingService: 빈 LineString으로 인한 선박 객체 누락 방지,
MAX_TRACKS_PER_CHUNK를 500,000으로 증가
- ChunkedTrackStreamingService: 2-pass 뷰포트 필터링 구현
Pass 1에서 뷰포트 교차 선박 ID를 수집하고, Pass 2에서 해당 선박의
전체 항적을 viewport 필터 없이 조회하여 선박 소실 현상 해결
- TrackConverter: 빈 geometry에서도 선박 객체 반환하도록 수정
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add GisControllerV2/GisServiceV2 for CompactVesselTrack responses
- Add nationalCode and shipKindCode fields to REST API responses
- Add flexible DateTime parsing support (multiple formats)
- Add TrackConverter utility for track data conversion
- Update SwaggerConfig with V2 API endpoints and unified tags
- Update ProdDataSourceConfig for prod-mpr profile support
- Enhance Swagger documentation for all DTOs