


취소와 장애에도 버티는 비동기 Rust 서비스 만들기
비동기 Rust 서비스를 만들 때 사용합니다. 목(mock)으로 때우지 않고 실제 코드를 끝까지 작성하고, 오류와 취소를 안전하게 처리하며, 실제 서비스 인터페이스로 테스트하고, 모든 검사를 통과한 뒤에 완료를 알립니다.
이 AI 규칙을 사용하려면
## 목이나 스텁 대신 실제 구현을 끝까지 완성하기
요청된 동작을 처음부터 끝까지 완성하세요. 누락된 프로덕션 로직을 모의 객체, 대체 구현, 뼈대 코드 또는 테스트 전용 지름길로 대신하지 마세요.
- 실제 종속성과 실제 통합 경로를 사용하세요.
- 고장 난 구현을 감추려고 테스트를 조작하지 마세요.
- 필수 설정을 건너뛰는 환경 우회책을 사용하지 마세요.
- 피할 수 없는 미완료 작업은 결과 계획이나 사양에 명시적으로 기록하세요.
- 사용자가 실제로 거칠 경로에서 얻은 증거 없이 기능이 작동한다고 절대 주장하지 마세요.
자율 실행은 엄격한 경로를 끝까지 완수한다는 뜻이지, 완료 기준을 낮춘다는 뜻이 아닙니다.
## 관련된 모든 데이터 종류에 같은 설계 결정을 적용하기
시스템이 서로 관련된 여러 신호 또는 데이터 계열을 처리한다면, 현재 한 계열이 우선순위이더라도 모든 계열에 적용되는 공통 동작을 설계하세요.
- 수집, 저장, 검색, 분석, 수명 주기 관리에 공통된 의미를 식별하세요.
- 계열별 최적화는 명시적인 경계 뒤에 두세요.
- 공통 결정이 처음 구현된 계열을 우연히 우대하지 않는지 테스트하세요.
- 모든 경로에서 오류, 구성, 관측 가능성 동작을 일관되게 유지하세요.
- 구현이 제각기 달라지도록 방치하지 말고 의도된 차이를 문서화하세요.
우선순위는 제공 순서를 정할 수 있지만, 아키텍처의 범위를 조용히 좁혀서는 안 됩니다.
## 안전을 첫째, 속도를 둘째, 편의를 셋째로 두기
엔지니어링 우선순위는 첫째 안전, 둘째 성능, 셋째 개발자 편의로 정하세요. 불변 조건과 실패 동작을 이해한 뒤에만 최적화하세요.
- 공개 경계에서 유효하지 않은 입력을 거부하세요.
- 명시적인 한도를 이름 있는 상수로 정의하고, 한도를 초과하면 구조화된 오류를 반환하세요.
- 종속성, 저장소 또는 네트워크의 실패를 성공으로 보이는 대체 동작으로 가리지 마세요.
- 예상하지 못한 상태를 성공한 무동작으로 처리하지 말고 오류 또는 불변 조건 위반으로 처리하세요.
- 계약에서 선택 사항이라고 명시한 경우에만 선택적 데이터의 누락을 허용하세요.
성능 작업은 실패, 재시도, 취소, 부분 진행 중에도 정확성을 보존해야 합니다.
## 내부 규칙은 디버그 단언으로, 잘못된 입력은 오류로 처리하기
검토자가 논리적으로 판단할 수 있는 내부 불변 조건은 디버그 전용 단언문으로 문서화하세요. 최적화된 빌드에서는 디버그 단언문이 사라질 수 있으므로, 유효하지 않은 사용자 입력, 외부 데이터, 런타임 조건에는 복구 가능한 오류 결과를 사용하세요.
- `Result`와 `?` 연산자로 라이브러리 오류를 전파하세요.
- 재사용 가능한 라이브러리 코드에서 값을 무조건 꺼내는 메서드를 피하세요.
- 모든 실패를 하나로 뭉개지 말고 의미 있는 오류 타입을 보존하세요.
- 오류가 정보를 담고 있다면 실패할 수 있는 파일 시스템 및 메타데이터 연산을 사용하세요.
- 원래 원인을 버리지 말고 맥락을 추가하세요.
- 사용하지 않는 대입으로 오류를 조용히 무시하지 마세요.
불가능한 상태는 진단할 수 있을 만큼 분명하게 실패해야 합니다.
## 작업이 취소되어도 안전한 비동기 코드 작성하기
비동기 작업은 어느 중단 지점에서든 취소될 수 있다고 가정하세요. 취소로 인해 일부만 갱신된 상태가 노출되거나 데이터가 손실되지 않도록 상태 전이를 구성하세요.
- 취소에 민감한 변경 가능 상태에는 액터 방식 소유권과 메시지 전달을 우선하세요.
- 비동기 대기 지점을 넘겨 잠금을 유지하지 마세요.
- 변경이 원자적으로 이루어져야 한다면 동기식 임계 구역을 사용하세요.
- 작업을 임의로 강제 중단하지 말고 취소 신호를 통해 협력적으로 취소하세요.
- 선택 루프에서는 진행 중인 비동기 연산을 고정해 이어서 실행하고, 매번 다시 만들어 폐기하지 마세요.
- 종료와 정리를 멱등적으로 만드세요.
액터 방식 코드와 비동기 코드에서는 더 단순한 복제나 공유 소유권이 소유권 및 취소 동작을 더 안전하게 만든다면 이를 선택하세요.
## 타입과 소유권을 명확히 하고 큰 파일 나누기
새로운 개념에 단순 문자열을 넘기지 말고 확립된 도메인 식별자와 타입 별칭을 사용하세요. 서로 섞어서는 안 되는 값을 타입 시스템이 구별하게 하세요.
- 함수 안에서 이름을 다시 정의해 상태 전이를 불분명하게 만들지 마세요.
- 소유권이 로컬에 남고 복제가 필요 없다면 참조를 반환하세요.
- 값이 작업 경계를 넘을 때는 공유 소유권을 명시적으로 사용하세요.
- 반복자 연결로 인해 실패 가능한 제어 흐름을 읽기 어려워진다면 절차적 반복문을 사용하세요.
- 지나치게 큰 파일과 함수는 일관된 책임에 따라 나누세요.
- 공개 인터페이스와 구현 세부 사항을 분리하세요.
코드가 비동기 상태를 조율할 때 가독성은 신뢰성을 높이는 도구입니다.
## 사용자가 실제로 쓰는 서비스 인터페이스로 테스트하기
기능을 실제 공개 계층 전체에서 실행해 보기 전에는 완료되었다고 선언하지 마세요. 사용자가 네트워크 프로토콜, 게이트웨이 또는 서비스 경계를 통해 동작에 접근한다면, 내부 함수를 직접 호출하지 말고 그 경계를 통해 테스트하세요.
1. 대표적인 구성으로 실제 서비스를 시작하세요.
2. 지원되는 수집 또는 명령 인터페이스를 통해 입력을 보내세요.
3. 지원되는 질의 또는 응답 인터페이스를 통해 결과를 가져오세요.
4. 영속성, 오류 매핑, 관측 가능한 부수 효과를 검증하세요.
5. 내부 동작과 공개 동작이 일치하는지 확인하세요.
내부 테스트는 유용하지만 프로덕션 경로를 통한 증거를 대신하지는 못합니다.
## 목적에 맞게 테스트 종류를 고르고 장애 테스트도 넣기
분리된 로직에는 빠른 단위 테스트를, 넓은 상태 공간에는 속성 기반 테스트를, 복원력에는 실패 주입 테스트를, 서비스의 전체 동작에는 통합 테스트를 사용하세요.
- 유용한 반례를 만들 수 있을 만큼 속성 기반 테스트의 입력 범위를 좁히세요.
- 저장 또는 프로토콜 동작이 중요하다면 실제 서비스 시험 환경을 사용하세요.
- 비결정적 스케줄링을 의도적으로 허용하는 테스트 모음에만 재시도를 제한하세요.
- 변경 사항이 복구 또는 상태 전이에 영향을 준다면 실패 지점 커버리지를 측정하세요.
- 새로운 공개 엔드포인트마다 통합 테스트를 추가하세요.
- 성공 경로만큼 의도적으로 오류 경로를 테스트하세요.
반복되는 재시도로 결정적 결함이 겉보기의 통과로 바뀌게 두지 마세요.
## 고정된 도구 체인과 저장소 명령으로 검사 실행하기
빌드, 서식 지정, 정적 검사, 테스트, 문서 검사, 라이선스 검사, 종속성 감사, 맞춤법 검사를 저장소에서 정의한 명령으로 실행하세요.
- 버전이 고정된 도구 체인과 필수 포매터 채널을 사용하세요.
- 선언된 로컬 서비스를 통합 테스트 모음 전에 시작하고 이후에 종료하세요.
- 실제 인증 정보를 포함하지 말고 문서화된 환경 변수를 통해 테스트 구성을 전달하세요.
- 영향받는 좁은 패키지를 먼저 실행한 다음 모든 기능을 포함한 작업 공간 전체 테스트 모음을 실행하세요.
- 정적 검사 경고는 모두 해결할 작업으로 취급하거나, 가장 작고 구체적인 예외로 정당화하세요.
- 각 변경 사항이 나중에 겹쳐 적용되는 변경의 일부일 때뿐만 아니라 독립적으로도 컴파일되는지 확인하세요.
직접 명령은 표준 작업 흐름이 수행한 설정을 보존하는 경우에만 허용됩니다.
## 아키텍처 변화를 세 종류의 기록으로 남기기
서로 보완하는 세 가지 기록으로 아키텍처 변경을 추적하세요.
- **특성:** 아키텍처가 충족해야 하는 선제적 요구 사항
- **격차:** 사고, 테스트 또는 프로덕션 동작을 통해 발견된 제약
- **일탈:** 선호하는 아키텍처에서 의도적으로 벗어난 사항과 그 근거 및 제약
코드 변경이 시스템 보장을 바꾼다면 관련 기록에 연결하세요. 지향하는 설계를 완성된 동작으로 오인하지 않도록 형식 모델, 시뮬레이션 작업 흐름, 의사결정 기록, 구현 상태를 서로 구분하세요.
새 기능이 발표될 때만이 아니라 증거로 인해 아키텍처가 바뀔 때 기록을 갱신하세요.
## 리뷰 댓글에는 그 댓글의 스레드 안에서 답하기
변경 내역은 초점을 좁게 유지하고 설명은 해당 결정에 연결해 검토하기 쉽게 만드세요.
- 같은 위치에 별도 댓글을 만들지 말고 기존 대화 흐름에서 검토 댓글에 답하세요.
- 호스팅 서비스 화면에서 답변이 의도한 상위 댓글에 연결되었는지 확인하세요.
- 명확하지 않은 불변 조건, 예외 허용, 복제 또는 일탈이 왜 필요한지 설명하세요.
- 관련 없는 구조 개선은 기능 변경과 분리하세요.
- 반복되는 실패 양상이 지속적인 규칙을 드러내면 계속 관리되는 지침을 갱신하세요.
체계적인 검토는 맥락을 보존하고 같은 문제가 여러 대화에서 동시에 해결되는 일을 막습니다.
## 완료를 알리기 전에 최종 diff에서 모든 검사 통과하기
완료를 보고하기 전에 최종 변경 내역을 살펴보고 다음을 확인하세요.
- 적용 가능한 모든 정적 검사가 설명되지 않은 경고 없이 통과합니다.
- 변경된 모든 소스 및 테스트 파일의 서식 검사가 통과합니다.
- 무조건적인 값 추출, 조용한 오류 억제 또는 정당하지 않은 복제가 남아 있지 않습니다.
- 프로덕션 인터페이스 테스트와 영향받는 통합 테스트가 통과합니다.
- 필수 헤더, 로그 규칙, 문서, 종속성 감사가 통과합니다.
- 새 파일과 함수의 범위가 명확하고 유지보수하기 쉽습니다.
- 인증 정보나 민감한 값이 없습니다.
실패의 원인을 직접 수정하세요. 통과 결과를 얻기 위해 검사를 비활성화하거나 테스트를 약화하거나 프로덕션 경로를 우회하지 마세요.
