한 예약이 오래 걸린다고 모든 프로젝트가 기다릴 필요는 없다. 반대로 같은 프로젝트의 두 예약이 다른 큐에 들어갔다는 이유로 동시에 실행되는 것도 곤란하다. 나는 짧은 기록 변경의 순서와 실제 업무의 점유를 다른 잠금으로 나눴다. 마지막 상태를 저장하는 동안의 점유까지 포함해 어디서 다음 실행을 허용할지 정했다.

예약 ID의 잠금과 프로젝트 차선은 목적이 다르다

ProjectJobs의 locked는 예약 ID마다 앞선 promise 뒤에 기록 변경을 연결한다. 같은 예약의 취소와 claim을 순서대로 읽기 위한 장치다. ProjectLanes는 workspaceId별 소유 증표를 보관해 같은 프로젝트의 두 실제 실행이 겹치지 않게 한다. 기록 한 개의 순서와 프로젝트 업무의 점유를 같은 값으로 표현하지 않는다.

긴 dispatch는 예약 메타데이터 잠금 바깥에서 기다린다. 그래서 다른 예약의 조회와 변경까지 실제 프로그램 종료를 기다릴 필요는 줄어든다. 나는 잠금이 있다는 사실보다 무엇을 잠그고 얼마나 오래 보관하는지를 먼저 보았다. 넓게 잡은 잠금은 정확성을 지켜도 불필요한 대기를 만들 수 있다.

서로 다른 큐도 같은 프로젝트를 알아야 한다

일반 예약과 카페 전달 큐는 내부 차선을 각각 가진다. 이것만으로는 서로 다른 큐의 같은 프로젝트를 알 수 없다. 앱은 두 큐에 공통 scheduledLanes의 claim을 넘겨 같은 workspace의 실행 자리를 함께 확인한다. 바깥 host 점유와 큐 내부 점유를 겹쳐 보호하는 구조다.

projectAvailable은 현재 프로그램과 노트북, task 상태와 미확정 결과 등을 본다. 화면에서 다른 프로젝트를 선택했다는 이유로 실행 자리가 비었다고 추정하지 않는다. 이 글은 저장된 대상 context의 설명보다 큐들이 실제 점유를 어떻게 공유하는지에 초점을 둔다. 대상 지정과 실행 자원 충돌은 다른 질문이다.

최종 저장 중에도 같은 프로젝트를 열지 않는다

dispatch가 끝났다고 release를 곧바로 부르지 않는다. 최종 상태와 실행 ID, 오류 기록이 정리되는 경로를 지난 뒤 finally에서 소유한 차선을 해제한다. 실제 작업과 기록이 어긋나는 구간에 같은 프로젝트의 다음 일을 넣지 않으려는 선택이다.

다른 프로젝트의 차선은 독립적이므로 이 기다림 때문에 모두 멈출 필요는 없다. 모든 업무가 빠르다는 성능 측정은 아니다. 실제로 보장하려는 것은 한 프로젝트의 점유가 다른 프로젝트의 불필요한 직렬화를 만들지 않는 구조다. 시간 개선률을 만들기보다 막아야 할 충돌과 허용할 진행을 분명히 했다.

시험은 저장을 붙잡고 이웃 프로젝트를 진행시킨다

기존 오류 시험은 일반 예약의 succeeded 저장을 gate로 붙잡는다. 같은 프로젝트의 카페 큐는 아직 실행하지 못해야 하고 다른 프로젝트는 완료로 진행해야 한다. gate를 푼 뒤 카페 작업이 시작되는지 확인한다. 실행 함수만 느리게 만든 시험보다 마지막 기록의 점유를 직접 보는 조건이다.

같은 큐 안에서도 한 프로젝트의 두 번째 항목은 queued에 남고 다른 프로젝트는 먼저 끝날 수 있는지 본다. 이 근거는 execute 대역과 파일 기록을 쓰는 기존 시험이다. 이번 콘텐츠 작업에서 실제 사용자 예약을 새로 만들지 않았고 해당 시험을 재실행하지 않았다. 코드와 기록된 검수 범위를 구분한다.

차선 증표는 옛 실행의 늦은 정리도 막는다

차선의 release는 현재 소유 증표와 같을 때만 상태를 지운다. 이전 실행이 이미 해제된 뒤 다시 release를 불러도 새 실행의 점유는 남는다. 오류 후 여러 정리 경로가 실행될 수 있으므로 중복 해제가 새 소유를 지우지 않는지 별도 시험이 필요했다.

공개한 차선 모듈은 이 소유 비교와 중지 요청의 상태를 독립적으로 시험하는 예제다. 파일 저장과 예약 큐 전체를 구현한 것은 아니다. 원래 코드의 저장 실패 시험과 모듈의 메모리 소유 시험을 합쳐 모든 운영 경합이 해결됐다고 하지 않는다. 작은 규칙이 어디에 연결되는지 설명하는 자료로 사용한다.

직렬과 병렬을 업무의 소유 기준으로 나눈다

모든 작업을 병렬로 하면 서로의 입력을 건드릴 수 있고 전부 직렬이면 필요 없는 대기가 생긴다. 나는 프로젝트를 실행의 소유 단위로 두고 기록 변경은 더 작은 예약 단위로 나눴다. 어느 화면이 보이는가보다 어떤 실행이 무엇을 점유하는지가 기준이다.

회사 프로그램도 문서 하나의 수정과 회사 전체 처리 잠금을 혼동하면 불편해진다. 정확성 때문에 필요한 기다림은 유지하되 관련 없는 작업까지 멈추게 하지 않아야 한다. 이 구조는 병렬 실행이라는 이름보다 누가 언제까지 실행 자리를 소유하는지 설명하는 방식에서 출발했다.