fix/issue-78-audio-cache #79
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Slovo_Propovedi/slovo-propovedi-mobile!79
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/issue-78-audio-cache"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Чинит #78 (краш iOS PWA при возобновлении «кешировать все») и добавляет жёсткую гарантию: трек считается закешированным, только если он скачан полностью — частичные записи не сохраняются и не отдаются.
Первопричина
cache.put, потом снова открывает/перезаписывает bucket (WebKit 260962 / 305539). Сценарий усугублялся тем, что веб при возобновлении заново fetch'ил и re-put'ил КАЖДЫЙ трек (натив пропускал закешированные файлы — веб нет).Изменения (10 коммитов)
246a585веб: пропуск уже закешированных треков (parity с нативом), восстановление повреждённого bucket Cache Storage (open→delete→reopen), устранены unhandled rejection'ы.d8d70a2веб: commit-manifest протокол — запись валидна ⇔ перечислена в__manifest__(манифест пишется только после успешного put); SW отдаёт аудио из кеша только для «закоммиченных» записей; одноразовая миграция старых записей. Натив: атомарность подтверждена (.part+ rename), предудаление осиротевшего.partтого же URL.d3edd9eочистка «осиротевших» файлов после нештатного завершения: натив — sweep*.mp3.partпри старте; веб — журнал активных скачиваний в AsyncStorage → адресное удаление без перечисления bucket (энумерация повреждённого bucket на iOS — риск crash-loop).89b651aфикс гонки запуска: sweep выполняется ДО initializePlayer; журнал валидируется zod; веб-очистка также убирает строки из манифеста.02a5faeguard в SW от пустого/битого манифеста; правки доков; отказоустойчивость нативного sweep; журнал очищается вместе с кешем; убран легаси-кастas.7dd0c9eвеб: реплей прогресса для позднего подписчика inflight-скачивания — мгновенно отдаёт текущийlastValue(parity с нативом).40068abвеб: multi-tab-безопасная очистка через «живость» журнала — записи{ url, sessionId, lastSeenAt }+ heartbeat 10с; удаляются только протухшие (>120с) записи: свежие = живое скачивание в другом табе; stale+закоммиченные — сохраняются, stale+незакоммиченные — удаляются.60a14b1ревью-фиксы: keying журнала по(sessionId, url), margin STALE_MS под троттлинг фоновых табов, переписанный тест late-joiner'а (реально проверяет реплей на inflight-скачивании), failure-path тест.c83b6f4веб: пути удаления/чтения больше не строят манифест —uncommitAudioUrlno-op без манифеста,hasCompleteAudio— только чтение + legacy-фолбэк.3b288edрефактор:summarizeAudioCache(легальное перечисление для статистики кеша,getCacheInfo) вынесен в модуль с предупреждением; гарантия в доках сфокусирована точно.Гарантии / инварианты
.mp3существует ⇔ трек полный (rename — точка коммита)summarizeAudioCache(getCacheInfo, сегодня без прод-вызовов, с предупреждением в коде)Проверка
Follow-ups (docs/debt.md)