C.W.K.
Stream
Lesson 02 of 05 · published

경로는 정체성이 아냐

~13 min · identity, bookmarks, revalidation

Level 0Finder 에서 길 잃음
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"/Users/you/report.pdf 라는 문자열은 주소지 사람이 아냐. 주소는 재배정돼."

같은 경로, 다른 파일

순진한 파일 매니저를 잡아먹는 버그가 여기 있어. 파일 하나 행을 보여줘. 사용자가 잠깐 시선을 돌려. 그 틈에 딴 프로세스가 그 파일을 지우고, 완전히 새롭고 무관한 파일을 정확히 같은 경로에 써 — 같은 이름, 같은 폴더. 사용자가 네 행에서 '휴지통으로 이동' 을 클릭해. 네 앱이 행동을 경로 문자열로 풀었으면, 방금 사용자가 본 적도 없는 파일을 휴지통에 넣은 거야. 경로는 같았고; 파일은 아니었어.

정체성은 북마크랑 리소스 ID 에 살아

macOS 는 경로보다 나은 핸들을 줘. 북마크는 이름변경이나 이동을 견딜 수 있는 질기고 재배치 가능한 참조야. 리소스 식별자 (URL 리소스 값 통해)는 이름이 아니라 실제 파일 객체에 묶여. Waygate 는 둘 다 LocationReference 로 감싸고 그걸 정체성으로 취급해 — 경로 문자열은 표시 힌트랑 최후 폴백으로만 남겨.

행동 전에 다시 검증해

좋은 참조를 쥐는 건 규칙의 절반일 뿐이야. 나머지 절반: 어떤 변형이든 전에, Waygate 는 다시 검증해 — 참조를 살아있는 파일시스템에 대해 풀고 볼륨 정체성, 리소스 정체성, 관련 전제조건이 여전히 성립하는지 확인해. 그러고서야 오퍼레이션이 진행돼. 더 이상 같은 파일로 안 풀리는 경로는 행동되지 않아; 표시(flag)돼.

경로 문자열은 절대 변형을 승인 안 해. Waygate 는 북마크랑 리소스 식별자를 갖고, 그걸 정체성으로 취급하고, apply 시점에 살아있는 URL·볼륨·전제조건을 다시 검증해. 행 위의 이름은 사람용 라벨이지, 엔진용 핸들이 아냐.
재사용된 경로 삭제. 파일 도구에서 제일 고약한 데이터 손실 버그는 지금 표시된 것과 다른 파일을 가리키는 경로에 행동하는 거야. SMB 랑 착탈식 볼륨이 더 나쁘게 만들어 — 공유가 재연결되면 정체성이 어긋나. 다시 검증을 건너뛰는 오퍼레이션은 불운한 레이스 하나만큼 엉뚱한 걸 휴지통에 넣기 직전이야.

Code

LocationReference: 경로가 아니라 정체성·swift
struct LocationReference {
    let bookmarkData: Data          // survives rename / move where possible
    let resourceID: String?         // ties to the file object, not the name
    let volumeID: String?           // which volume this identity belongs to
    let displayPath: String         // for humans + last-resort fallback ONLY
}

// Before a mutation, resolve and confirm identity still holds:
func revalidate(_ ref: LocationReference) throws -> URL {
    var stale = false
    let url = try URL(resolvingBookmarkData: ref.bookmarkData,
                      options: [], relativeTo: nil,
                      bookmarkDataIsStale: &stale)
    let values = try url.resourceValues(forKeys: [.fileResourceIdentifierKey,
                                                  .volumeIdentifierKey])
    guard matches(values, ref) else { throw OpError.identityChanged }
    return url   // safe to act on THIS url, now
}
경로만으로는 왜 위험한가·text
  t0: row shows  report.pdf   (file A, the one the user sees)
  t1: another process deletes A, writes B to the SAME path
  t2: user clicks 'Move to Trash' on the row

  PATH-BASED app:  trashes whatever is at the path now  -> trashes B (wrong!)
  WAYGATE:         revalidates identity, sees A is gone  -> stops, flags it

  Same string. Different file. Only identity tells them apart.

External links

Exercise

'재사용된 경로' 데이터 손실 버그의 사건 순서를 네 말로 적어봐: 파일 표시, 같은 경로 용도변경, 행동 실행. 그다음 그걸 멈추는 단 하나의 검사를 묘사해. 그 검사가 왜 '이 경로에 파일 있어?' 일 수 없어 — 대신 뭘 비교해야 해?
Hint
'여기 파일 있어?' 는 엉뚱한 파일에 대해 true 를 리턴해 — 그게 함정 전체야. 검사는 '여기 파일이 내가 표시한 그 파일이랑 여전히 같아?' 여야 하고, 그건 단순 존재가 아니라 리소스 정체성(북마크/리소스 id)을 비교한다는 뜻이야. 존재는 있음이고; 정체성은 같음이야.

Progress

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

댓글 0

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

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