15 / 24 · 실습
실습: 1024개 정지 패턴 검사
한 칸 버퍼의 hold·교체·비우기를 모든 10사이클 ready 패턴으로 검사합니다.
내용은 무료로 볼 수 있습니다. 수강 신청하면 학습 기록을 저장할 수 있어요.
정지해도 값과 순서를 보존하기
프로젝트에 elastic-model.mjs를 수동으로 추가하여 아래 파일을 저장하고 node elastic-model.mjs로 실행하세요. source는 네 거래를 순서대로 제시하며 수락될 때만 다음 항목으로 이동합니다. ready 패턴의 하위 비트는 에지 0, 그다음 비트는 에지 1에 대응합니다. 10개의 ready 비트 조합 1024개를 모두 시험하고 이후 소비자를 항상 ready로 만들어 남은 거래를 비웁니다.
출력은 에지 전 slot에서 전달하고, 새 입력 수락은 그 에지의 inReady로 결정합니다. 빈 슬롯은 소비자가 멈춰도 하나를 받을 수 있습니다. 반대로 꽉 찬 슬롯에서 ready=0이면 생산자는 next 인덱스를 증가시키지 않습니다. next를 매 에지 증가시키면 소스가 수락되지 않은 거래를 버리므로 버퍼가 올바르더라도 테스트 시스템은 잘못된 스트림을 만들어냅니다.
import assert from 'node:assert/strict';
const values = [0, 9, 255, 12];
let deliveries = 0;
for (let pattern = 0; pattern < 1024; pattern++) {
let slot = null, next = 0;
const seen = [];
for (let edge = 0; edge < 20; edge++) {
const ready = edge >= 10 || ((pattern >>> edge) & 1) === 1;
const old = slot;
const inReady = old === null || ready;
if (old !== null && ready) seen.push(old);
if (inReady) {
slot = next < values.length ? { tag: next, y: values[next] } : null;
if (slot !== null) next++;
} else {
assert.deepEqual(slot, old);
}
assert.equal(next - seen.length, Number(slot !== null));
}
assert.deepEqual(seen, values.map((y, tag) => ({ tag, y })));
assert.equal(slot, null);
deliveries += seen.length;
}
console.log(`ELASTIC PASS: 1024 patterns, ${deliveries} deliveries`);패턴 0은 처음 10에지 동안 소비자가 계속 멈춥니다. 에지 0에 tag0,y0을 빈 칸에 수락하고 에지 1~9에는 그것을 보존합니다. 에지 10에서 tag0를 전달하며 tag1,y9로 교체합니다. 이후 에지 11,12,13에서 tag1,2,3을 전달하므로 모든 항목이 끝납니다. 유효 값 0이 null로 오인되지 않는 것도 첫 거래가 확인합니다. 정상 메시지는 1024개 패턴과 총 4096개의 전달입니다.
next-seen.length는 현재까지 수락한 거래에서 전달한 거래를 뺀 값입니다. 이 값이 slot의 점유 0 또는 1과 같다는 검사는 출력 목록만 마지막에 보는 것보다 오류 위치를 좁혀 줍니다. 정지 중 old와 slot의 비교는 payload 보존을 검사합니다. 다만 이 예제의 단일 슬롯은 hold 분기에서 별도 계산을 하지 않으므로, 실제 구현과 비교할 때는 관측한 출력 값과 기준 모델의 old를 연결해야 합니다.
일부 패턴만 시험해 통과했다고 모든 길이의 정지에 대해 증명된 것은 아닙니다. 이 파일은 10사이클 제어 공간을 완전 열거하고 명시적 drain을 검사하는 유한 실행 시험입니다. 길이를 늘리거나 무작위 패턴을 더할 수 있지만, 무한 대기에서 완료를 요구해서는 안 됩니다. 소비자가 영원히 ready=0이면 보존은 요구할 수 있어도 완료는 보장할 수 없습니다. 기능 보존과 소비자의 진행 가정을 구분하여 테스트를 해석하세요.
직접 생각해 보기
패턴 0에서 에지 0~9 동안 source의 next는 얼마까지 증가하나요? 에지 10 후 점유와 next-seen.length는 얼마인가요?
해설 보기
에지 0의 한 항목만 수락하므로 next=1입니다. 에지 10에서 tag0를 전달하고 tag1을 수락하여 next=2, seen.length=1, 차=1이고 slot도 한 칸 점유합니다.