첫 모바일 음성 풀 리퀘스트 전에 롤백 연습하기
요약
모바일 음성 기능 개발 시, 첫 풀 리퀘스트(PR) 단계부터 철저한 롤백 및 예외 처리 연습이 중요합니다. 장치 모델, OS 빌드, 권한 상태 등 상세 스냅샷을 기록하고, '행복한 경로'뿐만 아니라 네트워크 손실, 마이크 거부 등 모든 실패 시나리오를 테스트해야 합니다.
핵심 포인트
- PR 전 녹화: 장치/OS 버전, 권한 부여 여부 등 환경 정보를 반드시 기록하세요.
- 롤백 연습: 성공 케이스 외의 모든 예외(네트워크 끊김, 백그라운드) 처리를 첫 PR에 포함해야 합니다.
- 경로 게이트 구현: 유닛 테스트를 통해 다양한 실패 시나리오에서 앱 동작을 제어하는 로직을 만드세요.
당신은 첫 출근 날에 음성 레포지토리에 합류했고, 스탠드업 미팅 전에 원격 전사(remote transcription) 경로를 요청하는 티켓이 있습니다. 대여용 전화기는 카페 Wi-Fi에 놓여 있는데, 다른 사람이 네트워크에 접속할 때마다 끊깁니다. 당신의 리뷰어는 첫 풀 리퀘스트가 두 번째 바이너리나 조용한 재시도 없이 롤백되기를 원합니다. 당신에게는 장치 하나, 시간 한 시간, 그리고 지연 시간이나 배터리 수치를 발명할 라이선스가 없습니다.
경로를 건드리기 전에 전화를 녹화하세요
파일을 수정하기 전에 노트 상단에 장치 모델, OS 빌드, 프레임워크 버전을 작성하세요. 이 새 설치에서 마이크 권한이 부여되었는지, 거부되었는지, 아니면 아직 요청되지 않았는지 기록하세요. 네트워크를 Wi-Fi, 셀룰러 또는 비행기 모드로 기록하고, 화면이 켜져 있는지 여부를 기록하세요. 모든 후속 관찰은 전체 장치군(fleet)의 모든 전화기에 대한 주장이 아니라 그 스냅샷에 연결된 것으로 취급하세요.
스냅샷 필드
- 패치 레벨이 설정 화면에 표시되는 경우를 포함한 장치 모델 및 OS 빌드.
- 사용할 오디오 및 네트워크 라이브러리의 프레임워크 및 종속성 버전.
- 마이크 권한, 네트워크 유형, 전원 공급원, 그리고 앱이 포그라운드 상태인지 여부.
- 리뷰어가 드릴을 승인할 때까지 꺼져 있어야 하는 경로 플래그 기본값.
풀 리퀘스트에 작은 의사결정표를 사용하여 리뷰어가 오디오가 휴대폰을 벗어날 수 있는 경우를 확인할 수 있도록 하세요. 원격 라우팅은 권한이 부여되고, 앱이 포그라운드 상태이며, 네트워크 확인이 방금 성공했을 때만 허용됩니다. 다른 모든 행은 버퍼를 프로세스 메모리에 유지하고 로컬 실패 상태를 표시해야 합니다. 이 표는 검토 보조 자료일 뿐 벤치마크가 아니며, 휴대폰에서의 에너지 사용량을 증명하지 않습니다.
검토표
| 앱 상태 | 마이크로폰 | 네트워크 | 경로 | 버퍼 |
|---|---|---|---|---|
| 포그라운드 | 부여됨 (granted) | 도달 가능 (reachable) | 원격 (remote) | 로컬 사본을 전송한 후 폐기 (send, then drop the local copy) |
| ... | ||||
| 읽는 순서는 장치에서 바깥으로 진행해야 하며, 데모가 포그라운드에서만 실행되기 때문에 백그라운드 행은 건너뛰지 마세요. 주니어 개발자는 종종 '행복한 경로(happy path)'를 한 번 테스트하고, 나머지 행들은 당연히 따라올 후속 작업으로 취급합니다. 이 나머지 행들이 바로 롤백이며, 나중에 티켓을 만드는 것보다 이 첫 풀 리퀘스트에 포함되어야 합니다. 만약 어떤 행이 폐기(discard)라고 되어 있다면, 코드는 해당 오디오 버퍼에 대한 재시도(retry)를 엔큐(enqueue)해서는 안 됩니다. |
제안된 경로 게이트 (Proposed route gate)
다음 함수는 첫 풀 리퀘스트를 위한 제안 예시이며, 장치 실험실의 보고서가 아닙니다. 모든 게이트를 통과하지 못하면 중지(stop)를 반환하는데, 이는 병합하기 전에 원하는 동작입니다. 휴대폰 없이 유닛 테스트할 수 있으며, 그 다음 대여 기기에서 동일한 케이스를 반복할 수 있습니다. 유닛 테스트는 권한 취소 확인을 대체할 수 없습니다. 왜냐하면 OS가 프로세스가 절전 상태일 때 상태를 변경할 수 있기 때문입니다.
type RouteInput = {
mic:
import { chooseRoute } from "./chooseRoute";
test("network loss stops the remote route", () => {
...
})
이 테스트는 도서관 네트워크가 끊겼을 때 나중에 수정된 내용이 오디오를 조용히 전송하는 것을 막기 위해 접근할 수 없는 행(row)에 잠금을 겁니다. 마이크 거부, 백그라운드 장면, 그리고 꺼진 플래그에 대한 형제 케이스들을 추가하세요. 저장소에서 테스트나 러너의 이름이 이 스니펫과 다르게 지정된 경우 파일에 '예시 제안' 레이블을 붙이세요. 이 파일 어디에도 지속 시간(duration), 토큰 수(token count), 또는 배터리 변화량(battery delta)을 단언하지 마세요.
## 개발 서버는 선택적 브랜치로만 사용하기
학습하는 동안 원격 브랜치를 개발 서버에 연결할 수 있습니다. 공개: 이 문서는 MonkeyCode의 제품 홍보의 일환으로 준비되었습니다. 운영자는 MonkeyCode가 이러한 종류의 시험을 위해 무료 모델 접근 및 무료 서버 옵션을 제공한다고 설명합니다.
이 문서는 모델, 할당량(quota), 지역 또는 기간을 명시하지 않는데, 해당 세부 정보들이 여기서 검증되지 않았기 때문입니다. 저장소나 스크린샷에 기본 URL, 토큰 또는 샘플 발화문을 하드코딩하지 마세요. 엔드포인트는 로컬에서 추적되지 않은 파일로부터 읽고, 그 파일을 첫 커밋에서 제외하세요. 무료 서버가 접근 불가능하면 플래그는 꺼진 상태로 돌아가고 전화기는 버퍼를 어떤 재시도 큐에서도 유지합니다.
### 커밋하지 않을 로컬 설정
local only; do not commit
.dev-server.env
제안된 추적되지 않은 파일입니다. 호스트를 실제로 받은 서버로 교체하세요.
DEV_SERVER_BASE_URL=https://your-dev-host.example
이 파일을 디버그 빌드에서만 로드하고, 변수가 누락되면 닫힌 실패(fail closed) 상태가 되도록 하세요. 릴리스 빌드는 별도의 검토된 설정 경로가 존재하는 경우가 아니면 라우트 플래그를 꺼진 상태로 유지해야 합니다. 토스트, 로그 라인 또는 풀 리퀘스트 스크린샷에 해결된 URL을 출력하지 마세요. URL이 어디서 왔는지 설명할 수 없다면, 할 수 있을 때까지 원격 브랜치를 푸시하지 않은 상태로 두세요.
## 풀 리퀘스트를 열기 전 명령어
제안된 로컬 검사입니다. 장치 측정은 하지 않습니다.
git status --short
git diff --stat
...
## 병합 전에 롤백 연습하기
### 제안된 순서
1. 라우트 플래그를 원격(remote)으로 설정하고, 여전히 이 장치, OS 빌드, 네트워크 이름을 명시했는지 확인합니다.
2. 포그라운드에서 짧은 캡처를 시작한 다음, 응답이 돌아오기 전에 비행기 모드를 활성화합니다.
3. UI가 로컬 실패(local failure)를 표시하는지 확인하고, 해당 캡처에 대한 재시도 작업이 남아있지 않은지 확인합니다.
4. 마이크 권한을 취소하고, 앱으로 돌아간 다음, 라우트가 중지(stop)로 반환되는지 확인합니다.
5. 앱을 백그라운드 상태로 한 분 동안 두고, 복원한 다음, 이전 버퍼가 폐기되었는지 확인합니다.
6. 플래그를 끄고(off), 앱을 다시 열어 이 설치본에서 원격 경로가 유휴 상태(idle)로 유지되는지 확인합니다.
이 순서를 제안된 테스트로 간주하고, 검토를 요청하기 전에 각 단계 옆에 실제로 본 것을 작성하십시오. 예상되는 동작은 중지된 라우트, 비워진 버퍼, 그리고 플래그가 꺼짐으로 돌아간 후 새로운 업로드가 없는 것입니다. 만약 복원 후에 캡처가 다시 나타난다면, 풀 리퀘스트를 중단하고 후속 조치보다는 실패로 기록하십시오. 이 테스트 통과에서 지연 시간이나 배터리 수치를 게시하지 마십시오. 왜냐하면 한 카페 세션이 측정 방법이 아니기 때문입니다.
## 롤백이 보이도록 풀 리퀘스트 작성하기
장치 스냅샷과 드릴 결과를 첨부하는 모든 스크린샷보다 위에 풀 리퀘스트 본문에 넣으십시오. 검토자는 코드 차이를 열어보지 않고도 플래그 기본값과 중지 조건을 확인해야 합니다. 만약 단계를 실행하지 않았다면, 휴대폰이 어떻게 했을지 추측하는 대신 '실행 안 함(not run)'이라고 작성하십시오. 그 정직함이 첫 시간의 요점이며, 나중 롤백이 이야기에 의존하는 것을 방지합니다.
장치(Device):
OS:
프레임워크(Framework):
...
## 첫 롤백에서 반드시 유지하지 말아야 할 것들
만약 발화(utterance)의 사본이 로그, 충돌 페이로드(crash payload), 또는 티켓에 첨부된 스크린샷으로 남아 있다면, 귀하의 롤백은 불완전합니다. 라우트가 `stop`을 반환할 때 인-메모리 버퍼(in-memory buffer)를 비우고, 나중에 재시도하기 위해 해당 버퍼를 디스크에 기록하는 것을 피하세요. 앱이 백그라운드로 전환될 때 화면에서 부분 텍스트를 제거하여 최근 보기(recents view)에 표시되지 않도록 하세요. 리뷰어에게 그러한 사본들을 찾아달라고 요청하세요. 왜냐하면 녹색 단위 테스트(green unit test)가 스크린샷을 잡아내지 못하기 때문입니다.
## 이 훈련을 사용하지 말아야 하는 사람들
프로덕션 용량 계획, 모델 비교 또는 릴리스 검토를 위한 배터리 예산이 필요한 경우 이 훈련은 건너뛰세요. 또한 이미 서명된 장치 연구실(device lab)과 필수 에너지 하네스(energy harness)를 보유한 팀에도 적합하지 않습니다. 대여 휴대폰을 사용하는 주니어는 이를 사용하여 첫 풀 리퀘스트(pull request)가 되돌릴 수 있고 조용한 상태로 유지되도록 할 수 있습니다. 플랫폼 소유자는 단 한 번의 카페 세션을 개발 서버가 빠르거나, 내구성이 있거나, 항상 사용 가능하다는 증거로 여겨서는 안 됩니다.
## 무엇을 돌려줘야 하는가
만약 이 훈련을 수행했다면, 장치, OS 빌드, 강제 전환(transition) 내용, 그리고 버퍼가 복구되었는지, 재시작했는지, 아니면 사라졌는지를 담아 회신하세요. 그 보고서는 다음 주니어가 검증되지 않은 숫자를 README에 복사하는 대신 기록을 비교하는 데 도움을 줍니다. 여러분이 받은 개발 서버에서도 동일한 플래그를 시도해보고, 브랜치를 떠나기 전에 해당 플래그를 비활성화하세요. 서버는 선택 사항으로 유지하고, 첫 병합된 경로(first merged path)가 휴대폰에서 `stop`할 수 있도록 유지하세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기