중복 만들지 않고 재시도하기
중복 만들지 않고 재시도하기
중복 작업을 만들지 않고 요청을 재시도해 봐요. 멱등성 키(idempotency key)는 하나의 논리적 연산, 예를 들어 특정 작업을 위한 샌드박스 생성을 식별해요.
출처: 문서
본문
인증된 클라이언트를 사용하세요. 키를 한 번 생성한 뒤, 재시도가 다른 프로그램 실행에서 일어날 수 있다면 그것을 작업과 함께 지속해요.
같은 생성 요청 재시도
모든 시도에서 같은 키와 페이로드를 재사용하세요. 예시는 일시적 가용성 거부를 재시도하고 SDK 자동 재시도를 비활성화해요. 자체 재시도 루프와 SDK의 재시도를 총 시도 횟수를 고려하지 않고 함께 실행하지 마세요.
마감과 경계 있는 시도 횟수를 사용하세요. 프로덕션 재시도 스케줄링을 위해 지연과 지터를 추가하거나 SDK의 구성된 재시도 동작을 사용하세요. 키를 유지한 채 페이로드를 바꾸는 것은 업데이트가 아니에요. 원래 요청과 충돌해요.
수락된 생성은 샌드박스의 리소스 데이터를 반환해요. 그 이름을 저장하고 클라이언트의 get 메서드를 사용해 핸들을 얻어요. 그것을 진행시키기 위해 생성을 반복하는 대신 그 리소스를 읽거나 대기해 진행을 따라가요.
핵심 코드:
for (let attempt = 0; attempt < attempts; attempt++) {
try {
return await client.kits.launch(
'shell',
{ displayName, resources: { cpus: 2, memoryMib: 4096 } },
{
idempotencyKey: requestId,
timeoutMs: 300_000,
signal,
maxRetries: 0,
},
);
} catch (error) {
if (
!(error instanceof RequestError) ||
error.raw.code !== 'unavailable' ||
attempt + 1 === attempts
)
throw error;
}
}
완전한 TypeScript 예시: idempotency/retry.ts
import { RequestError, type Sandboxes } from '@docker/sandboxes';
export async function createWithRetry(
client: Sandboxes,
displayName: string,
requestId: string,
attempts: number,
) {
if (!Number.isInteger(attempts) || attempts < 1)
throw new RangeError('attempts must be at least 1');
const signal = AbortSignal.timeout(300_000);
for (let attempt = 0; attempt < attempts; attempt++) {
try {
return await client.kits.launch(
'shell',
{ displayName, resources: { cpus: 2, memoryMib: 4096 } },
{
idempotencyKey: requestId,
timeoutMs: 300_000,
signal,
maxRetries: 0,
},
);
} catch (error) {
if (
!(error instanceof RequestError) ||
error.raw.code !== 'unavailable' ||
attempt + 1 === attempts
)
throw error;
}
}
throw new Error('attempt count was validated');
}
프로세스를 한 번 시작
프로세스를 자체 멱등성 키로 시작하고 반환된 프로세스 이름을 보관하세요. 응답이나 연결을 잃은 뒤에는 다른 프로세스를 시작하기 전에 그 프로세스를 찾으세요.
키가 모든 연산을 재생해도 안전하게 만들지는 않아요. 프로세스 입력, 신호, 파일 쓰기를 반복하면 두 번째 효과가 있을 수 있어요. 잃은 스트림에는 프로세스 재연결을 사용하고, 불확실한 쓰기를 반복하기 전에 파일을 검사하세요.
핵심 코드:
return sandbox.processes.start({ args }, { idempotencyKey: requestId });
완전한 TypeScript 예시: idempotency/unsafe.ts
import type { Sandbox } from '@docker/sandboxes';
export async function createProcessOnce(
sandbox: Sandbox,
args: string[],
requestId: string,
) {
return sandbox.processes.start({ args }, { idempotencyKey: requestId });
}