[Feat] GPS 노이즈 필터링으로 불필요한 DB 저장 절감#250
Conversation
수평 거리 10m 미만 + 고도 변화 3m 미만인 GPS 점을 서버에서 drop하여 DB 쓰기, Redis 통계 연산, 메모리 버퍼 사용량을 절감한다. - TrackingSessionStatsService에 getLastPosition() 읽기 전용 메서드 추가 - TrackingStreamConsumer에 shouldAcceptPoint() 필터 로직 추가 - Haversine 공식으로 수평 거리 계산 Closes #249
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 본 PR은 GPS 트래킹 데이터의 노이즈를 서버 측에서 필터링하여 불필요한 DB 쓰기 작업을 대폭 줄이는 것을 목적으로 합니다. 또한, 기존의 읽기-수정-쓰기 패턴을 Redis Lua 스크립트로 교체하여 동시성 안전성을 확보하고 시스템 효율성을 개선했습니다. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
이번 PR은 Redis Lua 스크립트를 도입하여 위치 정보 누적 및 통계 업데이트 작업을 원자적(atomic)으로 처리하도록 개선하고, GPS 노이즈 필터링 로직을 추가하여 불필요한 데이터 입력을 방지합니다. 이에 대해 리뷰어는 매 GPS 수신마다 발생하는 Redis 조회 성능을 최적화하기 위해 인메모리 캐싱을 적용할 것과, getLastPosition 메서드에서 multiGet 결과에 대한 방어적인 null 및 크기 체크를 추가하여 안정성을 높일 것을 제안했습니다.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| public LastPosition getLastPosition(Long sessionId) { | ||
| HashOperations<String, String, String> hash = redisTemplate.opsForHash(); | ||
| String key = statsKey(sessionId); | ||
| List<String> values = hash.multiGet(key, List.of("last_lat", "last_lng", "last_altitude")); | ||
| return new LastPosition( | ||
| parseNullableDouble(values.get(0)), | ||
| parseNullableDouble(values.get(1)), | ||
| parseNullableDouble(values.get(2)) | ||
| ); | ||
| } |
There was a problem hiding this comment.
[P3] getLastPosition에서 multiGet 결과에 대한 방어적 null 체크 추가
redisTemplate.opsForHash().multiGet은 Redis 연결 장애, 파이프라인/트랜잭션 환경 등 다양한 원인으로 인해 null을 반환할 가능성이 있습니다. 또한, 반환된 리스트의 크기가 예상보다 작을 경우 IndexOutOfBoundsException이 발생할 위험이 있습니다.
안전한 실행을 위해 values가 null이거나 크기가 부족한 경우를 대비한 방어적 코드(Null-safe guard)를 추가하는 것을 권장합니다.
public LastPosition getLastPosition(Long sessionId) {
HashOperations<String, String, String> hash = redisTemplate.opsForHash();
String key = statsKey(sessionId);
List<String> values = hash.multiGet(key, List.of("last_lat", "last_lng", "last_altitude"));
if (values == null || values.size() < 3) {
return new LastPosition(null, null, null);
}
return new LastPosition(
parseNullableDouble(values.get(0)),
parseNullableDouble(values.get(1)),
parseNullableDouble(values.get(2))
);
}- shouldAcceptPoint에서 Redis HMGET 대신 ConcurrentHashMap 캐시 우선 조회 - recordPoint 성공 시 캐시 갱신, 세션 종료 시 캐시 제거 - getLastPosition의 multiGet 결과에 null/size 방어 코드 추가
Summary
TrackingSessionStatsService에getLastPosition()읽기 전용 메서드 추가TrackingStreamConsumer.onMessage()에서recordPoint()호출 전 노이즈 필터 적용변경 파일
TrackingSessionStatsService.java—LastPositionrecord +getLastPosition()메서드 추가TrackingStreamConsumer.java—shouldAcceptPoint()필터 +haversineMeters()거리 계산 추가기대 효과
Test plan
Closes #249