본문 바로가기
반응형

전체 글350

dataclass에서 mutable default 오류가 나는 이유와 해결법 @dataclass에서 목록이나 딕셔너리를 기본값으로 넣으려다 ValueError: mutable default ... is not allowed를 만나는 경우가 있다. 기본값 하나를 여러 객체가 공유하면 한 객체의 변경이 다른 객체에도 섞일 수 있기 때문에 dataclass가 위험한 선언을 막는 것이다.이럴 때는 field(default_factory=list)처럼 기본값 자체가 아니라 새 값을 만드는 함수를 전달한다. 객체가 생성될 때마다 함수가 다시 호출되므로 각 인스턴스가 서로 다른 목록이나 딕셔너리를 갖게 된다.왜 빈 목록을 바로 넣을 수 없을까?다음 코드는 현재 Python에서 클래스가 정의되는 시점에 예외가 발생한다.from dataclasses import dataclass@dataclas.. 2026. 9. 8.
GitHub Actions Docker 빌드가 느릴 때: cache-from·cache-to로 캐시 적용 GitHub Actions에서 Docker 이미지를 빌드할 때 매번 모든 레이어를 처음부터 만들면 의존성 설치 구간에서 시간이 많이 든다. Dockerfile을 바꾸지 않았는데도 npm ci, pip install, Gradle 의존성 다운로드가 반복된다면 빌드 캐시가 다음 실행으로 이어지지 않는지 먼저 확인할 만하다.docker/build-push-action의 cache-from과 cache-to를 사용하면 BuildKit 캐시를 GitHub Actions 캐시 저장소에 보관했다가 다음 빌드에서 다시 가져올 수 있다. 핵심은 캐시를 읽는 설정과 저장하는 설정을 함께 두고, 여러 이미지를 빌드한다면 캐시 범위를 나누는 것이다.먼저 확인할 구조캐시가 적용되는 흐름은 다음과 같다.워크플로가 이전 Build.. 2026. 9. 8.
asyncio gather와 TaskGroup 비교: 예외가 발생하면 무엇이 달라질까? asyncio.gather()로 여러 코루틴을 실행하다 하나가 실패하면 다른 작업은 어떻게 되는지 헷갈릴 수 있다. 예외가 바로 올라오니 나머지도 함께 취소됐다고 생각하기 쉽지만 기본 동작은 그렇지 않다.Python 3.11부터 사용할 수 있는 asyncio.TaskGroup은 한 작업이 실패하면 같은 그룹의 나머지 작업을 취소하고, 그룹을 빠져나갈 때 예외를 묶어 전달한다. 여러 작업을 하나의 단위로 다루고 싶을 때 차이가 분명해진다.gather와 TaskGroup의 핵심 차이두 기능 모두 여러 코루틴을 동시에 실행하지만 실패를 다루는 기준이 다르다.항목asyncio.gather()asyncio.TaskGroup기본 목적awaitable의 결과를 입력 순서대로 모음관련 작업의 생성과 종료 범위를 함께 .. 2026. 9. 6.
GitHub Actions에서 AWS 액세스 키 없애기: OIDC 배포 역할 연결 GitHub Actions로 AWS에 배포할 때 AWS_ACCESS_KEY_ID와 AWS_SECRET_ACCESS_KEY를 Secrets에 넣는 예제가 많다. 동작은 단순하지만 키가 오래 유지되고, 교체 시점도 직접 관리해야 한다는 부담이 남는다.OIDC를 사용하면 워크플로가 실행될 때만 AWS STS에서 짧은 수명의 자격 증명을 받아 쓸 수 있다. 설정은 조금 늘어나지만 장기 액세스 키를 GitHub에 저장하지 않는다는 차이가 크다.OIDC 방식의 흐름전체 흐름은 다음 네 단계로 볼 수 있다.GitHub Actions가 OIDC 토큰을 발급받는다.워크플로가 토큰과 함께 AWS 역할을 요청한다.AWS가 역할의 신뢰 정책과 토큰의 sub 조건을 확인한다.조건이 맞으면 STS가 실행 시간에 사용할 임시 자격.. 2026. 9. 6.
브랜치를 바꾸지 않고 동시에 작업하기: Git worktree로 폴더 분리 작업 중인 브랜치에 수정 파일이 남아 있는데 긴급 수정이나 다른 기능을 함께 진행해야 할 때가 있다. 매번 커밋하거나 git stash로 치운 뒤 브랜치를 바꾸면 현재 흐름을 잃기 쉽다.git worktree를 사용하면 하나의 Git 저장소에 작업 폴더를 추가해 서로 다른 브랜치를 동시에 열 수 있다. 저장소 전체를 다시 복제하는 방식이 아니라 공통 Git 데이터는 공유하고, 각 폴더의 작업 파일과 HEAD, index는 따로 관리하는 구조다.worktree는 무엇을 나눠 가질까?기본 작업 폴더도 하나의 worktree다. git worktree add를 실행하면 같은 저장소에 연결된 작업 폴더가 하나 더 만들어진다.공유하는 항목worktree마다 분리되는 항목커밋 객체, 대부분의 refs, 저장소 기본.. 2026. 9. 4.
Docker Compose가 DB보다 먼저 시작될 때: depends_on과 healthcheck로 해결 docker compose up을 실행했는데 API 컨테이너가 데이터베이스 연결 오류를 내고 재시작되는 경우가 있다. depends_on을 이미 적었는데도 문제가 생기면 컨테이너가 실행된 시점과 내부 서비스가 요청을 받을 준비를 마친 시점을 구분해야 한다.Compose는 의존성 순서에 따라 컨테이너를 시작하지만, 짧은 문법의 depends_on만으로 데이터베이스 준비 완료까지 기다리지는 않는다. 이때 데이터베이스의 healthcheck와 condition: service_healthy를 함께 사용하면 API를 시작할 조건을 명확하게 만들 수 있다.depends_on만으로 부족한 이유데이터베이스 컨테이너 프로세스가 시작돼도 초기화, 복구, 테이블 준비 때문에 실제 연결을 받기까지 시간이 더 필요할 수 있다.. 2026. 9. 4.
반응형