diff --git a/Frameworks/RSWeb/RSWeb/OneShotDownload.swift b/Frameworks/RSWeb/RSWeb/OneShotDownload.swift index fd3beed24..455e94d65 100755 --- a/Frameworks/RSWeb/RSWeb/OneShotDownload.swift +++ b/Frameworks/RSWeb/RSWeb/OneShotDownload.swift @@ -65,11 +65,6 @@ private struct WebCacheRecord { let dateDownloaded: Date let data: Data let response: URLResponse - - func isExpired(_ timeToLive: TimeInterval) -> Bool { - - return Date().timeIntervalSince(dateDownloaded) > timeToLive - } } private final class WebCache { @@ -77,18 +72,19 @@ private final class WebCache { private var cache = [URL: WebCacheRecord]() func cleanup(_ cleanupInterval: TimeInterval) { - + + let cutoffDate = Date(timeInterval: -cleanupInterval, since: Date()) cache.keys.forEach { (key) in let cacheRecord = self[key]! - if shouldDelete(cacheRecord, cleanupInterval) { + if shouldDelete(cacheRecord, cutoffDate) { cache[key] = nil } } } - private func shouldDelete(_ cacheRecord: WebCacheRecord, _ cleanupInterval: TimeInterval) -> Bool { + private func shouldDelete(_ cacheRecord: WebCacheRecord, _ cutoffDate: Date) -> Bool { - return Date().timeIntervalSince(cacheRecord.dateDownloaded) > cleanupInterval + return cacheRecord.dateDownloaded < cutoffDate } subscript(_ url: URL) -> WebCacheRecord? { @@ -115,26 +111,24 @@ private final class DownloadWithCacheManager { static let shared = DownloadWithCacheManager() private var cache = WebCache() private static let timeToLive: TimeInterval = 10 * 60 // 10 minutes - private static let cleanupInterval: TimeInterval = 30 * 60 // 30 minutes + private static let cleanupInterval: TimeInterval = 5 * 60 // clean up the cache at most every 5 minutes + private var lastCleanupDate = Date() func download(_ url: URL, _ callback: @escaping OneShotDownloadCallback) { - cache.cleanup(DownloadWithCacheManager.cleanupInterval) + if lastCleanupDate.timeIntervalSinceNow < -(5 * 60) { + lastCleanupDate = Date() + cache.cleanup(DownloadWithCacheManager.timeToLive) + } let cacheRecord: WebCacheRecord? = cache[url] - if let cacheRecord = cacheRecord, !cacheRecord.isExpired(DownloadWithCacheManager.timeToLive) { + if let cacheRecord = cacheRecord { callback(cacheRecord.data, cacheRecord.response, nil) return } OneShotDownloadManager.shared.download(url) { (data, response, error) in - if let _ = error, let cacheRecord = cacheRecord { - // In the case where a cache record has expired, but the download returned an error, we use the cache record anyway. By design. - callback(cacheRecord.data, cacheRecord.response, nil) - return - } - if let data = data, let response = response, response.statusIsOK, error == nil { let cacheRecord = WebCacheRecord(url: url, dateDownloaded: Date(), data: data, response: response) self.cache[url] = cacheRecord