본문 바로가기
C.W.K.
Stream
Lesson 04 of 05 · published

절반짜리는 목적지가 될 수 없어

~12 min · pause-cancel, partial, cleanup

Level 0Finder 에서 헤매는 중
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"취소는 '세상을 되돌려' 가 아니야. '깔끔하게 멈추고, 확실히 내 것인 것만 치워' 지."

멈춤과 취소는 서로 맞춰서

오래 걸리는 복사는 중간에 세울 수 있어야 해. 그런데 아무 순간에나 끊으면 작업이 어디까지 갔는지 모르는 상태가 남아. 그래서 Waygate 는 멈춤과 취소를 안전한 지점에서만 받아. 여러 파일을 복사할 땐 파일과 파일 사이에서, 큰 파일을 옮길 땐 덩어리와 덩어리 사이에서 요청을 확인하지. 그 지점에선 상태가 분명하고 저널도 앞뒤가 맞으니까 멈춤이 깔끔해.

절반짜리는 절대 승격 안 돼

이 레슨이 지키는 핵심은 이거야. 절반쯤 쓰인 임시본이 목적지 행세를 하는 일은 없어. 복사를 도중에 취소하면 그 임시본은 진짜 이름을 못 받아. 이름을 받는 건 확인을 통과한 뒤뿐인데, 취소된 복사는 거기까지 못 갔으니까. 사용자는 작업이 멈춘 걸 보지, 목적지 이름을 단 잘린 파일을 보지 않아. 취소는 이름을 주기 전에 길을 끊는 거야.

치우는 것도 자기 것만

취소된 작업은 뒤처리를 할 수 있는데, 확실히 자기 것인 임시본만, 그것도 애매한 구석이 없을 때만 치워. .waygate-stage-op_7a3f 는 저널이 이 작업 소유이고 끝나지 않았다고 증명하니까 지워. 자기가 만들었다고 증명 못 하는 건 손도 안 대. 애매하면 남기고 표시할 뿐, 넘겨짚어서 지우지 않아. 폴더 복사는 메인 스레드 밖에서 필요한 만큼만 훑고, 진행 표시도 바이트와 항목 수와 지금 파일과 알 수 없는 부분을 나눠서 보여줘. 그래야 멈췄을 때 엔진이 이해하는 자리에 서게 되거든.

멈춤과 취소는 안전한 지점에서만 받고, 절반짜리는 이름을 못 받고, 뒤처리는 확실히 자기 것만 건드려. 멈춤은 상태가 분명한 자리에서 일어나. 취소된 복사는 딱 봐도 미완성인 임시본만 남기지, 목적지 이름을 단 잘린 파일을 남기지 않아.
정직한 진행 표시는 UX 만이 아니라 안전 장치야. 옮긴 바이트와 끝난 항목 수와 지금 파일과 알 수 없는 부분을 나눠 보여주는 건 예쁜 막대 얘기가 아니야. 멈춤이 진짜 지점에 떨어지게 하고, 복구가 어디까지 갔는지 따질 수 있게 하는 거지. 퍼센트 하나로 뭉개면 엔진이 안전하게 멈추는 데 필요한 정보까지 같이 가려져.

Code

안전 지점에서만 받고, 저널이 증명한 것만 치우기·swift
func copyItems(_ items: [URL], _ plan: OperationPlan) async throws {
    for (i, item) in items.enumerated() {
        try Task.checkCancellation()          // safe checkpoint: BETWEEN items
        if await controls.isPaused { await controls.waitUntilResumed() }
        let staged = try await copyOne(item, plan)
        try await journal.mark(plan.id, .itemStaged(i), evidence: staged)
    }
}

func onCancel(_ plan: OperationPlan) async throws {
    // Delete ONLY staging items the journal proves belong to this op:
    for artifact in journal.ownedStagingArtifacts(plan.id) {
        if journal.isUnambiguouslyOwned(artifact) {
            try? FileManager.default.removeItem(at: artifact)
        } // else: leave it, flag it -- never a speculative delete
    }
}

External links

Exercise

파일 100개를 네트워크 공유로 복사하다가 40번째에서 취소했다고 하자. 끝난 상태가 어때야 맞아? 목적지엔 뭐가 있고, 임시본은 어떻게 되고, 뭐가 치워졌고, 저널엔 뭐라고 적혀? 그다음 '취소는 전부 되돌리기' 가 왜 놀랍고 위험한지 설명해봐.
Hint
맞는 상태는 이래. 1~39 번은 확인까지 끝나 목적지에 있고 그대로 남아. 40 번 임시본은 치워지고(저널이 우리 것이고 미완성이라고 증명하니까). 41~100 번은 시작도 안 했고. '전부 되돌리기' 는 제대로 도착한 39 개를 도로 지운다는 뜻이야. 사용자한테도 뜻밖이고, 엉뚱한 걸 지울 기회만 새로 만들지. 취소는 멈추는 거지 되감는 게 아니야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인 — 댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.