노트북 셀을 두 번 누르거나 응답을 늦게 읽었다고 같은 입력을 다시 전달하면 외부 행동도 반복될 수 있다. 나는 같은 실행 안의 SDK 요청에는 이미 시작한 promise를 이어 쓰게 했다. 다만 이것을 모든 사이트의 정확히 한 번 처리나 재시작 뒤 영구 중복 방지라고 설명하지 않는다. 보호하는 수명을 먼저 정했다.
재사용 전에 현재 실행의 연결인지 확인한다
SDK 요청에는 runId와 접근 자격, method와 key, inputs가 들어간다. 호스트는 전달한 자격과 실행 ID가 맞고 현재 active가 그 실행이며 닫히지 않았는지 확인한다. 같은 문자열의 업무 이름만 보고 과거 결과를 돌려주는 캐시가 아니다. 지금 유효한 실행 연결의 요청인지 먼저 판단한다.
이 자격은 프로그램 소스와 일반 결과에 복사할 자료가 아니다. 실행이 종료되거나 중지돼 연결이 닫히면 해당 요청의 수명도 끝난다. 같은 key를 다른 새 실행에서 보냈다고 이전 promise를 찾는 전역 조회 기능도 없다. 연결 확인과 결과 재사용의 범위를 같은 실행에 묶었다.
첫 요청의 key와 입력 지문을 함께 남긴다
첫 요청에서는 key와 inputs의 지문을 보관한다. 이후 같은 실행에 다른 key나 다른 지문이 들어오면 RUN_REPLAY_INPUT_CHANGED다. key만 같으면 내용이 달라도 같은 결과를 반환하는 식으로 처리하지 않는다. 반대로 내용이 같더라도 key가 다르면 같은 요청이라고 추측하지 않는다.
이 경로의 지문은 JSON.stringify한 입력 사전의 SHA-256이다. 키 순서를 정규화하는 별도 정렬이 없으므로 같은 값의 사전을 다른 순서로 만들면 다르게 보일 수 있다. 나는 이 구현을 의미적으로 같은 모든 입력을 찾아내는 비교라고 말하지 않는다. 호출자가 일관된 요청 자료를 유지하는 것도 계약의 일부다.
동작을 다시 만들지 않고 같은 promise를 기다린다
active.promise가 없을 때만 repeatProgram과 executeRecipe의 실행을 만든다. 이미 있으면 그 promise를 기다리고 보관한 결과를 반환한다. 첫 요청이 끝나기 전의 두 번째 요청도 새로운 실행을 시작하는 대신 같은 진행을 본다. 반환이 늦었다는 사실을 업무가 시작되지 않았다는 근거로 쓰지 않는다.
실패한 promise도 이 수명에서 새 성공 요청으로 갈아끼우지 않는다. 결과를 읽는 일과 행동을 다시 전달하는 일을 나누기 위한 결정이다. 일부 서비스에 이미 전달된 입력은 로컬 응답이 끊겨도 남아 있을 수 있다. 나는 통신 재시도와 업무 재실행을 같은 함수 이름 안에 숨기지 않으려 했다.
같은 실행 보호와 영속 원장은 다른 층이다
active의 key와 promise는 메모리 상태다. 앱을 다시 켰을 때 이 객체를 되살려 무조건 이어 주는 기능은 아니다. 실행 상태를 디스크에서 읽으면 예전 running 기록을 needs_review로 돌려주는 경로가 있다. 원래 결과를 확인하지 않고 새 실행 ID로 같은 행동을 보내면 이 보호 밖의 새 요청이 된다.
프로젝트 업무 노트북의 job_id·항목 ID 원장은 다른 층에서 이어하기를 다룬다. 이름이 비슷하다고 두 기능의 보장을 합쳐 설명하지 않는다. 전자는 살아 있는 실행의 재진입을 묶고 후자는 여러 실행 사이에 항목 기록을 남긴다. 재사용을 설계할 때 어느 수명이 필요한지부터 정해야 했다.
코드에서 확인한 경계를 시험 범위와 구분한다
이 글은 SDK의 요청 형식과 runner의 active 검사, 입력 비교와 promise 보관을 직접 읽어 정리했다. 원래 브라우저에서 새 SDK 중복 요청을 보내 실험하지 않았다. 프로젝트 노트북의 기존 시험은 완료 항목을 다시 호출할 때 실제 execute 횟수가 늘지 않는지 별도로 확인한다.
그 시험은 원장을 다루는 다른 층의 근거다. 나는 그것을 이 연결 경로의 모든 오류와 끊김을 새로 검수한 결과로 옮겨 쓰지 않는다. 아래 기다리기 모듈도 기존 실행의 상태를 읽는 독립 예제이며 SDK promise 게이트의 복제판은 아니다. 비슷한 보호라도 무엇을 실제로 확인했는지 구별한다.
늦게 답이 온다는 이유로 새로 시작하지 않는다
실제 사용에서는 진행 표시가 잠잠하면 같은 버튼을 다시 누르고 싶어진다. 이때 좋은 결과 화면은 새 요청을 만드는 버튼보다 기존 실행 ID와 현재 상태를 읽는 통로를 먼저 제공해야 한다. 나는 재사용 규칙을 숨은 최적화가 아니라 사용자가 기다리는 이유를 설명하는 자료로 보고 있다.
회사 프로그램에서도 승인과 전송 같은 행동은 같은 문제가 있다. 기다리던 응답이 늦는 것과 처리가 실행되지 않은 것은 다르다. 같은 실행의 결과를 다시 받는 기능과 정말 새 업무를 시작하는 기능을 구분해야 한다. 작은 promise 보관도 그 구분을 실행 코드에 남기는 방법이었다.