마지막 업데이트 2026-07-22
수업 활동의 리소스(이미지·영상·오디오)를 입장 전 미리 받아 Cache Storage에 저장(프리캐시)하고, 재생 시 캐시에서 꺼내 쓰는 시스템. 다운로드 실패 시 입장을 차단(#15)해 수업 중 끊김을 방지한다.
`https://dubu-cache/${fileName}?v=${updatedAt}`
caches.open(CACHE_NAME). 실패(시크릿 모드/스토리지 비활성)면 이벤트 추적 후 throw → 입장 차단.POST /api/resources/urls {fileNames, isLowPerformanceDevice} → 파일별 {url(presigned), updatedAt}. (저사양이면 저화질 URL) 이 단계 실패는 서버 presigned 발급 문제로 S3 다운로드 실패와 별도 추적.cache.match → 있으면 완료 처리, 없으면 다운로드 목록에 추가. 메타데이터 없는 파일은 failed에 넣고 fail-fast(받아도 입장 차단되므로 다운로드 생략).fetchResumable(Range 이어받기+3회 재시도) → blob → new Response(blob)로 cache.put(성공 후에만).{ failed }: 3회 재시도 후에도 못 받은 목록. 호출부(#15)가 비어있지 않으면 입장 차단.onProgress(current, total)로 진척 통지(호스트 입장 승인 UI의 캐싱 진행률).
프리캐시되지 않은 리소스를 재생 시점에 on-demand로: presigned URL 발급 → 버전 키 cache.match → 없으면 fetchResumable → cache.put. 인메모리 responseCacheMap/blobUrlsMap으로 같은 세션 내 재요청 가속.
components/ui/service-worker-clean-up.tsx, next.config.mjs(PWA 설정). 오프라인/캐싱 전략 지원.caches.delete(CACHE_NAME)(clearCache).use-resource-processing — 업로드 후 비동기 트랜스코딩 상태 폴링(완료돼야 프리캐시 가능).lib/resource-collector.ts — 활동에서 필요한 파일명 목록 추출(cacheResources 입력).| 파일/심볼 | 역할 |
|---|---|
| use-resource-cache.ts (cacheResources L88, getCacheKey L83) | 프리캐시·lazy·버전 키 |
| lib/fetch-resumable.ts | Range 이어받기·재시도 다운로드 |
| hooks/use-resource-processing.ts | 비동기 처리 상태 폴링 |
| lib/resource-collector.ts | 활동 리소스 파일명 수집 |
| api/resources/urls/route.ts | presigned URL + updatedAt 발급 |
| components/ui/service-worker-clean-up.tsx, next.config.mjs | SW/PWA |