문제 & 원인
상품을 획득하는 과정에서 리워드가 지급해야 하는 것보다 더 많이 발급이 된다는 것을 확인이 되었다. 리워드를 지급하는 로직에서 Redis에 캐싱해 둔 데이터 객체 내부 값을 변경하여 사용하고 있었다.
변경된 객체로 Redis 캐시를 업데이트 하지 않았기 때문에 초기에 작성했을 때는 버그를 발생시키는 않는 로직이었을 것이다. 하지만 추후에 또 다른 개발자 분이 Redis의 부하를 줄이고자 인메모리 캐싱을 추가하였다. 리워드 보상에서 사용이 되는 데이터가 계속해서 업데이트 되어 인메모리 캐시에 저장이 되었고 이 때부터 문제가 발생하게 된 것이다.
불변 객체
불변 객체 장점은 로직을 처리하는 과정에서 객체 내부의 값이 변경이 되었을 때 발생하는 사이드 이펙트를 방지할 수 있기에 코드의 안정성을 보장할 수 있다는 것이다. 이번 버그가 객체 내부 값이 변경이 되는 상태에서 서로의 코드가 영향을 주어 발생 하였기에 이 장점을 살릴 수 있겠다는 생각이 들었다. 프로젝트에서 사용하는 자바, 코틀린에서는 불변 객체를 위한 기능을 제공을 하고 있어 쉽게 적용할 수 있다는 것도 있었다.
깊은 복사
불변 객체가 되었을 때 전달 할 값이 변경이 되어야 한다면 각 값들을 분리해서 넣거나 객체를 복사해서 보내줘야 한다. 객체 내부 값들이 로직에서 많이 사용이 되기 때문에 복사를 해서 보내 주기로 했다. 객체 내부에도 객체가 있을 수 있기 때문에 얕은 복사를 했을 경우 문제가 동일하게 발생하게 될 것이다. 내부 객체도 모두 복사가 될 수 있도록 깊은 복사로 코드를 수정을 했다.
적용 결과
불변 객체와 깊은 복사를 모두 적용하니 버그는 수정이 되었다. 이번 경험을 통해서 이론적으로만 알던 불변 객체와 깊은 복사가 왜 사용이 되어야 하는지를 알게 되었다.
'프로젝트' 카테고리의 다른 글
Redis Scan으로 Key 삭제하기 (0) | 2024.12.07 |
---|---|
시간 유효성 검사에서 시간 값 생성 시점 (0) | 2024.11.03 |
Github PR을 했을 때 Slack 알림 보내기 (0) | 2024.10.21 |
재화(크레딧, 투표권 등) 로그 데이터 정리 작업 (0) | 2024.09.02 |
AWS SQS 메시지 소비할 때 Visibility Timeout 문제 (0) | 2024.08.04 |