Ruby에서 예외 발생 후 코드를 다시 실행하는 방법을 다룰 때 retry 키워드를 소개한 적이 있습니다. 그런데 retry에는 잘 알려지지 않은 짝꿍이 있는데, 바로 redo입니다. 두 키워드는 비슷하게 작동하지만, redo는 블록 전체가 아니라 루프의 현재 반복(iteration)만 다시 실행한다는 점이 다릅니다.
redo 키워드 이해하기
이전 AppSignal Academy 아티클에서 배웠듯이, retry를 사용하면 블록 안의 코드를 처음부터 다시 실행할 수 있습니다.
이 예제는 예외를 발생시키기 전에 콘솔에 "Iteration"이라는 단어를 출력합니다. 이후 rescue 블록이 실행되면서 retry를 호출하고, 블록 전체가 다시 처음부터 시작됩니다. 결과적으로 프로그램은 Iteration을 무한히 출력하게 됩니다.
redo 키워드를 사용하면 루프에서도 비슷한 효과를 얻을 수 있습니다. 특히 배열을 순회하면서 특정 조건에서 재시도가 필요한 상황에서 매우 유용합니다.
위 코드는 다음과 같은 결과를 출력합니다.
여기서 주목할 점은 반복 카운트가 그대로 유지된다는 것입니다. redo는 실행 흐름을 루프의 시작 지점으로 되돌리지만, 반복 횟수 자체는 증가시키지 않습니다. 참고로 아래처럼 retry를 사용한 코드도 정확히 동일한 출력을 만들어냅니다.
redo를 활용하면 루프 안에서 손쉽게 재시도 로직을 구현할 수 있습니다. 다음 예제에서는 처리해야 할 작업(job) 큐가 있으며, 각 작업은 :success 또는 :failure를 반환합니다. 우리는 작업이 성공할 때까지 동일한 루프 반복을 계속해서 다시 실행합니다.
next 키워드 이해하기
현재 반복의 시작점으로 되돌아가는 대신, 다음 반복으로 건너뛰고 싶다면 next를 사용하면 됩니다.
위 코드는 다음과 같은 결과를 출력합니다.
이번에는 반복 카운터가 계속 증가하는 것을 확인할 수 있습니다. 대부분의 경우 개발자가 원하는 동작은 next입니다. 다만 루프가 정확히 정해진 횟수만큼 실행되어야 하거나, 배열을 순회하는 도중에 에러 처리와 재시도가 필요하다면 redo를 적극적으로 고려해 보세요.
루프에서 반복을 다시 실행하는 다양한 방법에 대해 새롭게 배운 내용이 있었기를 바랍니다. 이 글이나 AppSignal Academy 시리즈의 다른 아티클에 대한 의견이 있다면 언제든지 알려주세요. 더 깊이 알고 싶은 Ruby 주제가 있다면 그것도 환영합니다.
Thijs Cadier
최고기술책임자(CTO) 겸 공동창업자. 인프라 작업을 위해 몇 달씩 모습을 감추기도 하며, 회사의 수십억 건에 달하는 요청이 올바르게 처리되도록 책임집니다. 회사 최고의 드러머이기도 합니다.