중복 만들지 않고 재시도하기

중복 만들지 않고 재시도하기

중복 작업을 만들지 않고 요청을 재시도해 봐요. 멱등성 키(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 });
}

더 알아보기 (Learn more)