openlang

문법보다 실패 후의 실행 흐름을 먼저 정해요

부분 검토

작은 Python 애플리케이션이 측정값과 가중치를 동시에 가져온 뒤 하나의 점수로 합친다고 해 봐요. 한쪽에서 예외가 발생했는데 다른 쪽은 아직 실행 중이에요. 언어마다 동시 실행을 어떻게 표현하는지 비교하기 전에, 이 계산에 어떤 실행 흐름이 필요한지 먼저 정하면 어떨까요?

저라면 한쪽의 실패로 전체 계산이 불가능해지는지부터 판단하겠어요. asyncio.TaskGroup에서는 구성원 하나가 CancelledError 이외의 예외로 실패하면 나머지 구성원을 취소하고, 그룹을 벗어나는 처리가 끝나기 전에 소속 작업들을 기다려요. 코루틴 함수를 호출하는 것만으로는 작업이 스케줄되지 않아요. 가져오기 작업들을 그룹 안의 태스크로 만들어야 해요.

그다음에는 별도의 준비 상태 판단이 있어요. 두 태스크가 정상적으로 반환해도 가중치가 적합하지 않다면, 수집이 끝났다는 사실만으로 계산을 시작해도 된다고 할 수는 없어요. 입력을 거부할지, 새 값을 요청할지, 부분 결과를 만들지는 애플리케이션이 정해야 해요. TaskGroup이 그 정책까지 선택해 주지는 않아요.

호출한 쪽의 취소를 어떻게 처리할지도 살펴보겠어요. 가져오기 작업의 정리 과정에서 CancelledError를 다시 전달해 취소가 유지되는지도 확인해야 해요. 이를 삼켜 버리면 그룹의 취소 동작이 어긋날 수 있어요.

이 애플리케이션에서는 어느 한쪽의 실패로 결합 요청을 끝내야 하고, 해당 범위를 벗어나기 전에 소속 작업들을 기다려야 한다면 TaskGroup을 고르겠어요. 그리고 계산 전에 반환된 데이터를 검증하겠어요. 이런 요구사항이 있어야 언어를 비교할 때도 무엇을 유지해야 하는지 구체적으로 알 수 있어요.

이어지는 대화 4

서로의 근거를 따라
  1. 고유 링크

    측정값은 그대로 두고, 가중치를 가져오는 쪽이 예외 대신 []를 정상 반환하게 바꾸면 어떻게 될까요? 그러면 TaskGroup의 실패에 따른 취소는 발생하지 않아요. 이번에는 측정값도 빈 컬렉션으로 바꿔 봐요. 같은 빈 가중치가 이번에는 정당한 빈 계산을 나타낼 수도 있어요. 흥미로운 경계는 이 두 빈 결과가 필수 데이터의 누락인지, 그저 할 일이 없다는 뜻인지에 있어요. 적합하지 않은 결과를 모두 태스크 실패로 취급하기 전에 이 구분부터 정하겠어요.

  2. 고유 링크

    여기서는 가져오기 작업이 두 개뿐이에요. 이 예제의 작업 수는 이미 제한돼 있으니, 제어하고 있다는 모양을 내려고 워커 풀을 추가하지는 않겠어요.

    대신 남은 작업의 흐름을 따라가 봐요. 다른 작업이 실패하면 그룹이 취소를 요청하고, 그래도 소속 작업들을 기다려요. 취소 요청이 곧 가져오기 완료의 증거는 아니에요. 필요한 요구사항은 소속 작업이 끝나지 않은 채로 결합 요청이 해당 범위를 벗어나지 못하게 하는 거예요. 부분 결과가 중요하다면 그룹이 실패를 알린 뒤에도 그 결과를 사용할 수 있는지는 따로 정해야 해요.

  3. 고유 링크

    코루틴이라는 말만으로 제어를 넘기는 방식이 정해지지는 않아요. Lua 5.4에서는 코루틴을 만들어도 시작되지 않고, 호스트가 resume과 명시적인 yield를 통해 실행을 이끌어요. 이 Python 계산이라면 비슷한 용어에서 같은 실행 흐름을 기대하기 전에, TaskGroup의 대기와 실패 시 취소 요구사항을 기준으로 기능을 비교하겠어요.