계좌를 바꾸면 최근 내역도 새 계좌 기준으로 바뀌어야 했다. 그런데 네트워크가 느린 환경에서 빠르게 전환하면 이전 계좌의 결과가 새 화면에 나타났다. 다시 한 번 바꾸거나 화면을 닫았다 열면 정상으로 돌아와서 재현도 쉽지 않았다.
처음에는 캐시를 비우지 않은 문제라고 생각했다. 목록을 무조건 지우도록 고치자 잘못된 결과는 줄었지만, 화면이 자주 비었다가 다시 채워져 사용감이 나빠졌다. 원인은 단순히 오래된 데이터가 남은 게 아니라 오래된 요청이 늦게 끝난 것이었다.
요청을 보낸 계좌와 현재 계좌가 달랐다
응답 처리 코드는 결과만 받고 현재 선택된 화면에 그렸다. 요청할 때 어떤 계좌였는지 정보가 사라져 있었다.
void LoadHistory(string accountId)
{
api.GetHistory(accountId, result =>
{
Render(result);
});
}
콜백이 실행되는 시점의 현재 계좌와 요청 당시 계좌가 같다는 보장이 없었다. 계좌 정보를 함께 캡처하고 적용 전에 비교해야 했다.
void LoadHistory(string requestedAccount)
{
api.GetHistory(requestedAccount, result =>
{
if (requestedAccount != currentAccount)
return;
Render(result);
});
}
캐시는 키와 함께 봐야 했다
화면 전환을 빠르게 하려고 마지막 결과를 보관하고 있었는데, 캐시가 어느 계좌의 값인지 명확하지 않은 부분도 있었다. 데이터만 저장하면 나중에 출처를 알 수 없었다.
Dictionary<string, HistoryResult> cacheByAccount;
계좌를 키로 나누고, 갱신 시각이나 만료 조건까지 함께 두니 이전 값과 새 값을 구분하기 쉬워졌다. 모든 데이터를 캐시할 필요는 없지만 적어도 캐시의 범위는 이름과 구조에서 보여야 했다.
화면을 먼저 비울지 기다릴지도 정책이었다
계좌를 바꾸는 순간 이전 목록을 바로 숨길지, 새 결과가 올 때까지 남겨 둘지 결정해야 했다. 잘못된 계좌 정보가 보일 위험이 있는 화면이라면 바로 로딩 상태로 바꾸는 편이 안전했다. 반대로 단순한 참고 화면이라면 이전 값을 흐리게 보여 주며 갱신할 수도 있었다.
당시에는 기존 화면 정책을 따라 전환 즉시 선택과 상세 상태를 닫고 로딩을 표시했다. 기술적으로 가능한 선택보다 사용자가 오해하지 않는 선택이 중요했다.
비동기 문제는 느릴 때 더 잘 보였다
로컬 환경에서는 요청이 빨라 순서가 거의 뒤집히지 않았다. 개발 도구로 지연을 주고 빠르게 계좌를 연속 전환해 보니 재현이 쉬워졌다. 정상 속도에서 한 번 성공한 건 순서 문제가 없다는 증거가 아니었다.
이후 비동기 화면을 테스트할 때 일부러 늦은 응답, 연속 클릭, 화면 닫기 후 응답을 확인한다. 계좌 전환 버그를 고치며 “현재 상태가 무엇인가”뿐 아니라 “이 결과가 어느 상태에서 시작됐는가”를 함께 보게 됐다.