[Fix] Redis Lua 스크립트 누락 파일 추가#251
Conversation
tracking-stats-update.lua가 버전 관리에 포함되지 않아 prod 배포 시 ClassPathResource 로딩 실패하던 문제 해결
|
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은 배포 환경에서 Redis Lua 스크립트 파일을 찾지 못해 발생하는 런타임 오류를 해결하기 위해 누락된 리소스 파일을 프로젝트에 포함하는 변경 사항입니다. 이를 통해 정상적인 GPS 통계 갱신 및 트래킹 데이터 저장이 가능해집니다. 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
This pull request introduces a new Redis Lua script, tracking-stats-update.lua, designed to calculate and update tracking statistics (such as distance, ascent, descent, max altitude, and point count) within a Redis hash. The review feedback suggests a valuable performance optimization: merging multiple individual HGET and HSET calls into single HMGET and HSET operations (using unpack for dynamic arguments) to minimize Redis CPU overhead under high-throughput conditions.
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.
| local prev_lat = tonumber(redis.call("HGET", key, "last_lat")) | ||
| local prev_lng = tonumber(redis.call("HGET", key, "last_lng")) | ||
| local prev_altitude = tonumber(redis.call("HGET", key, "last_altitude")) | ||
| local distance_total = tonumber(redis.call("HGET", key, "distance_total")) or 0 | ||
| local ascent_total = tonumber(redis.call("HGET", key, "ascent_total")) or 0 | ||
| local descent_total = tonumber(redis.call("HGET", key, "descent_total")) or 0 | ||
| local max_altitude = tonumber(redis.call("HGET", key, "max_altitude")) | ||
| local point_count = tonumber(redis.call("HGET", key, "point_count")) or 0 | ||
|
|
||
| if prev_lat and prev_lng then | ||
| local rad = math.pi / 180 | ||
| local dLat = (lat - prev_lat) * rad | ||
| local dLng = (lng - prev_lng) * rad | ||
| local a = math.sin(dLat / 2) * math.sin(dLat / 2) | ||
| + math.cos(prev_lat * rad) * math.cos(lat * rad) | ||
| * math.sin(dLng / 2) * math.sin(dLng / 2) | ||
| local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) | ||
| distance_total = distance_total + 6371000.0 * c | ||
| end | ||
|
|
||
| if altitude and prev_altitude then | ||
| local delta = altitude - prev_altitude | ||
| if delta > 0 then | ||
| ascent_total = ascent_total + delta | ||
| elseif delta < 0 then | ||
| descent_total = descent_total + (-delta) | ||
| end | ||
| end | ||
|
|
||
| if altitude and (not max_altitude or altitude > max_altitude) then | ||
| max_altitude = altitude | ||
| end | ||
|
|
||
| point_count = point_count + 1 | ||
|
|
||
| redis.call("HSET", key, | ||
| "last_lat", tostring(lat), | ||
| "last_lng", tostring(lng), | ||
| "last_recorded_at", recordedAt, | ||
| "distance_total", tostring(distance_total), | ||
| "ascent_total", tostring(ascent_total), | ||
| "descent_total", tostring(descent_total), | ||
| "point_count", tostring(point_count)) | ||
|
|
||
| if altitude then | ||
| redis.call("HSET", key, "last_altitude", tostring(altitude)) | ||
| end | ||
| if max_altitude then | ||
| redis.call("HSET", key, "max_altitude", tostring(max_altitude)) | ||
| end |
There was a problem hiding this comment.
[P2] Redis Lua 스크립트 내에서 개별 HGET 및 HSET 호출을 여러 번 수행하는 것은 Redis 서버의 CPU 오버헤드를 증가시킬 수 있습니다. 특히 k6 부하 테스트와 같이 고처리량(High-throughput) 환경에서는 이러한 개별 호출이 성능 병목의 원인이 될 수 있습니다.
해결 방안:
- 여러 개의
HGET호출을 단일HMGET호출로 병합하여 읽기 성능을 최적화합니다. - 조건부로 추가되는 필드들을 Lua 테이블에 담아
unpack을 활용함으로써 단일HSET호출로 병합하여 쓰기 성능을 최적화합니다.
local stats = redis.call("HMGET", key, "last_lat", "last_lng", "last_altitude", "distance_total", "ascent_total", "descent_total", "max_altitude", "point_count")
local prev_lat = tonumber(stats[1])
local prev_lng = tonumber(stats[2])
local prev_altitude = tonumber(stats[3])
local distance_total = tonumber(stats[4]) or 0
local ascent_total = tonumber(stats[5]) or 0
local descent_total = tonumber(stats[6]) or 0
local max_altitude = tonumber(stats[7])
local point_count = tonumber(stats[8]) or 0
if prev_lat and prev_lng then
local rad = math.pi / 180
local dLat = (lat - prev_lat) * rad
local dLng = (lng - prev_lng) * rad
local a = math.sin(dLat / 2) * math.sin(dLat / 2)
+ math.cos(prev_lat * rad) * math.cos(lat * rad)
* math.sin(dLng / 2) * math.sin(dLng / 2)
local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
distance_total = distance_total + 6371000.0 * c
end
if altitude and prev_altitude then
local delta = altitude - prev_altitude
if delta > 0 then
ascent_total = ascent_total + delta
elseif delta < 0 then
descent_total = descent_total + (-delta)
end
end
if altitude and (not max_altitude or altitude > max_altitude) then
max_altitude = altitude
end
point_count = point_count + 1
local hset_args = {
"last_lat", tostring(lat),
"last_lng", tostring(lng),
"last_recorded_at", recordedAt,
"distance_total", tostring(distance_total),
"ascent_total", tostring(ascent_total),
"descent_total", tostring(descent_total),
"point_count", tostring(point_count)
}
if altitude then
table.insert(hset_args, "last_altitude")
table.insert(hset_args, tostring(altitude))
end
if max_altitude then
table.insert(hset_args, "max_altitude")
table.insert(hset_args, tostring(max_altitude))
end
redis.call("HSET", key, unpack(hset_args))
References
- Prioritize findings in this order: bugs, data consistency, security, performance, design, maintainability, readability. (link)
🧾 요약
tracking-stats-update.lua가.gitignore되지 않았지만 버전 관리에 포함되지 않아 prod 배포 시ClassPathResource로딩 실패recordPoint())이 동작하지 않아 트래킹 포인트 저장 불가 현상 발생✅ 확인