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

파일은 파일시스템 거야

~12 min · canonical, projection, ownership

Level 0Finder 에서 헤매는 중
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"디스크가 데이터베이스야. 네 앱은 창고가 아니라 창문이고."

진짜는 어디 있나

제대로 된 파일 관리자는 코드 한 줄 쓰기 전에 질문 하나에 답해야 해. 진짜는 어디 있지? 솔깃한 오답은 '내 앱 안에' 야. 디스크 전체를 빠르게 훑어 색인을 만들고, 그걸 보여주고, 어긋나면 나중에 맞추자는 거지. 빨라 보이지만 함정이야. 색인과 디스크가 어긋나는 순간 — 그리고 반드시 어긋나, 다른 앱도 Finder 도 OS 도 다 파일을 건드리니까 — 네 앱은 자신만만하게 거짓말을 보여주게 돼.

Waygate 의 답

파일은 파일시스템 거야. 그걸로 끝. 바이트도, 이름도, 속성도, 권한도, 볼륨 내용도 전부 있는 자리에서 진짜야. Waygate 의 DB 가 담는 건 딱 세 가지. 작업 공간(어느 폴더를 열어뒀는지, 창은 어떻게 놓였는지), 위치 참조(파일을 복사하지 않고 가리키기만 하는 북마크와 식별자), 그리고 작업 기록(뭘 했는지 남긴 저널). 디렉토리 사본은 없어.

비추기만 한다는 규율

페인에 보이는 건 그때그때 폴더를 읽어서 줄로 그린 결과야. 앱을 껐다 켜면 '파일들' 이 되살아나는 게 아니라 폴더 위치가 되살아나고, 거기서 다시 읽어. 꺼져 있는 동안 폴더가 바뀌었으면 새로 읽은 게 그 변화를 그대로 보여줘. 낡아버릴 캐시가 없어. 애초에 캐시를 안 만들었으니까.

진짜는 살아 있는 파일시스템이고, 브라우저는 그걸 비춘 화면이야. Waygate 는 위치와 작업 기록만 남기지, 나중에 권위 행세를 할 디렉토리 사본은 안 남겨. 앱이 아는 것과 디스크가 다르면 언제나 디스크가 이겨. 설계가 그래.
내가 처음 그린 Waygate 구조엔 로컬 '파일 색인' 테이블이 있었어. 트리를 캐시해 두면 전부 빠릿해질 거라 생각했거든. 아빠가 거기 화살표 하나를 그었어. 디스크에서 앱으로. 그러고 말했지. "진짜가 흐르는 방향은 이거 하나뿐이야." 그날 밤 색인 테이블을 지웠어. 그 뒤로 내가 안 겪은 골치 아픈 버그들 — 낡은 줄, 유령 파일, 엉뚱한 걸 지운 삭제 — 은 전부 진짜를 두 벌 안 갖고 있어서 생긴 여유였어.

Code

Waygate DB 가 담는 것과 안 담는 것·text
  WAYGATE SQLITE STORES            WAYGATE SQLITE NEVER STORES
  --------------------            ---------------------------
  workspace: open folders,        a copy of the directory tree
    tabs, window layout           file contents / bytes
  references: bookmarks +         'the list of files in /some/folder'
    resource identifiers          anything treated as the truth
  operation journal (evidence)      about what's on disk right now

  The disk is the database. This SQLite file is a notebook
  ABOUT the disk, never a copy OF it.
한 줄 한 줄은 그릴 때마다 새로 읽어·swift
// A browser row is derived from a live URL each time it's shown,
// not read back from a stored snapshot.
struct BrowserRow {
    let reference: LocationReference   // bookmark + resource id (points AT the file)
    // display values below are PROJECTED from a fresh read, never authoritative:
    var displayName: String
    var size: Int64?
    var modified: Date?
}

// On refresh, we re-resolve the reference against the live filesystem.
// If it no longer resolves, the row goes visibly offline -- we do NOT
// invent a value from the last time we saw it.

External links

Exercise

이미 없는 파일을 앱이 보여준 적을 떠올려봐. 지운 걸 계속 가리키는 '최근 파일' 목록이라든가, 파일이 있다고 우기는 동기화 클라이언트라든가. 진단해봐. 그 앱은 진짜를 어디에 두고 있었길래 디스크와 어긋났을까? '캐시 말고 다시 읽기' 였으면 어떻게 막혔을까?
Hint
유령 파일 버그는 거의 다 낡아버린 두 번째 진짜 때문이야. 앱이 목록을 저장해 두고 디스크가 그 뒤로 달라진 걸 몰랐던 거지. '파일시스템이 진짜, 캐시 말고 다시 읽기' 는 성능 선택이 아니라, 없는 파일을 안 보여줄 유일한 방법이야.

Progress

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

댓글 0

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

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