설정은 '지금 어디로'만 압니다: 캘린더 목적지를 바꾸자 옛 블록이 남은 이유

· 약 3분

이 글은 태스크를 라우팅 규칙에 따라 캘린더에 블록으로 쓰는 플러그인을 고친 커밋 하나를 다룹니다. 근거는 그 커밋 기록 하나뿐입니다.

알려진 것: 설정을 보면 위치를 안다

라우팅 설정에는 “이 태스크는 이 캘린더로 보낸다"가 적혀 있습니다. 그래서 설정만 읽으면 블록이 어디 있는지도 안다고 생각하기 쉽습니다. 정리할 때도 설정에 적힌 캘린더만 훑으면 된다는 생각이 여기서 나옵니다.

실제로 확인한 것: 목적지를 바꾸면 옛 블록이 남는다

커밋 기록을 보면 재라우팅 정리는 현재 목적지만 훑었습니다.

목적지를 A에서 B로 바꾸면 A는 목록에서 빠지고, A에 남은 블록은 아무도 지우러 가지 않았습니다.

삭제 경로도 같은 목록을 썼기 때문에, 태스크를 지워도 옛 캘린더에는 블록이 남았습니다.

커밋은 문제를 이렇게 적었습니다. 설정만으로는 “이 태스크가 어디에 있었는가"를 알 수 없습니다.

둘의 차이: 원인이 두 겹이었습니다

이 사례에서는 원인 두 개를 나눠서 봐야 합니다.

첫째, 블록이 남은 원인입니다. 정리 대상이 현재 목적지로만 정해져 있었습니다. 설정은 “지금 어디로 보내는가"를 담을 뿐 “전에 어디에 썼는가"는 담지 않습니다. 그래서 목적지가 바뀌는 순간 옛 캘린더는 정리 대상에서 빠졌습니다.

둘째, 검사가 비어 있던 원인입니다. 검사에 쓰는 PluginAPI 가짜 객체에는 저장소가 없어서, 새로 만든 기록이 조용히 비어 있었습니다. 커밋에 따르면 저장소가 없는 상태로는 고친 동작 자체가 검사되지 않습니다. 이것은 원래 버그를 만든 원인이 아닙니다. 고친 동작을 검사하려다 드러난 별개의 구멍입니다. 원래 버그를 기존 검사가 왜 잡지 못했는지는 커밋에 적혀 있지 않습니다.

어떻게 고쳤는가

플러그인이 블록을 쓴 캘린더를 스스로 기록하게 했습니다(persistDataSynced).

정리 대상은 현재 목적지와 기록된 캘린더의 합집합입니다.

실패했을 때의 동작도 정해 두었습니다.

  • 기록을 읽지 못하면 현재 목적지만 훑습니다. 기록이 생기기 전의 동작이며, 읽기 실패가 쓰기를 막지는 않습니다.
  • 저장에 실패해도 이번 세션 동안은 기록이 메모리에 남고, 다음 쓰기가 저장을 다시 시도합니다.

manifest는 1.1.0으로 올렸고 ZIP을 다시 묶었습니다.

검증: 커밋 기록에 적힌 것

아래는 커밋 기록을 옮긴 것입니다. 이 글을 쓰면서 검사를 다시 돌리지는 않았습니다.

커밋 기록에 따르면 라우터 검사 41건이 통과했고, 그중 1건이 새로 추가된 검사입니다.

새 검사는 목적지를 바꾼 뒤 옛 캘린더로 삭제가 나가는지를 봅니다.

커밋 기록에 따르면 합집합을 빼면 이 검사가 실패하는 것을 확인한 뒤 코드를 되돌려 놓았습니다.

확인하지 못한 것

  • 실제 운영 캘린더에 옛 블록이 몇 개 남아 있는지는 확인하지 못했습니다.
  • 수정 뒤 실제 캘린더에서 옛 블록이 지워지는 것도 직접 확인하지 않았습니다.
  • 이 기록이 생기기 전에 옛 캘린더에 남은 블록이 새 정리 대상에 들어가는지는 커밋 기록만으로 알 수 없습니다.

그래서 이 글에는 남은 블록을 손으로 지우는 절차를 적지 않았습니다. 어떤 블록이 플러그인 것인지 가려내는 방법도, 잘못 지웠을 때 되돌리는 방법도 근거에 없습니다. 지울 대상과 복구 방법을 모른 채 삭제를 권할 수는 없습니다.

그래서 무엇이 달라지는가

이 사례에서 가져갈 것은 세 가지입니다.

  • 설정은 의도이지 이력이 아닙니다. 이 사례에서 정리 코드에 필요했던 것은 “지금 어디로 보내는가"가 아니라 “전에 어디에 썼는가"였습니다. 이 커밋은 플러그인이 블록을 쓴 캘린더를 스스로 기록하도록 고쳤습니다.
  • 가짜 객체가 무엇을 갖췄는지도 검사의 일부입니다. 이 사례에서는 가짜 객체에 저장소가 없어 새 기록이 조용히 비었고, 고친 동작이 검사되지 않았습니다. 새 동작이 어떤 기능에 기대는지 보고, 가짜 객체에 그 기능이 있는지부터 확인해야 합니다.
  • 새 검사는 고친 부분을 빼서 실패하는 것을 본 뒤에 믿습니다. 이 커밋은 합집합을 빼서 검사가 실패하는 것을 확인했습니다. 그 확인이 없으면 통과했다는 사실만으로는 검사가 무엇을 지키는지 알 수 없습니다.