77//
88
99import Foundation
10- import os . log
10+ import OSLog
1111
1212public final class TranscriptDownloader {
1313
14- private let log = OSLog ( subsystem: Transcripts . subsystemName, category: String ( describing: TranscriptDownloader . self) )
14+ private let log = Logger ( subsystem: Transcripts . subsystemName, category: String ( describing: TranscriptDownloader . self) )
1515
1616 let loader : Loader
1717 let manifestURL : URL
@@ -39,7 +39,7 @@ public final class TranscriptDownloader {
3939 private var validSessionIdentifiers : [ String ] ?
4040
4141 public func fetch( validSessionIdentifiers: [ String ] ? = nil , progress: @escaping ProgressHandler , completion: @escaping CompletionHandler ) {
42- os_log ( " %{public}@ " , log: log , type : . debug, #function)
42+ log. debug ( #function)
4343
4444 transcriptCountLoaded = 0
4545
@@ -51,10 +51,10 @@ public final class TranscriptDownloader {
5151 }
5252
5353 private func callCompletion( ) {
54- os_log ( " COMPLETED " , log : self . log , type : . default )
54+ log . debug ( " COMPLETED " )
5555
5656 if !failedTranscriptIdentifiers. isEmpty {
57- os_log ( " Failed transcript IDs: %@ " , log : self . log , type : . default , failedTranscriptIdentifiers. joined ( separator: " , " ) )
57+ log . debug ( " Failed transcript IDs: \( self . failedTranscriptIdentifiers. joined ( separator: " , " ) , privacy : . public ) " )
5858 }
5959
6060 queue. async { [ weak self] in
@@ -80,7 +80,7 @@ public final class TranscriptDownloader {
8080 coalescer. run ( for: [ contents] , queue: queue) { [ weak self] coalescedContents in
8181 guard let self = self else { return }
8282
83- os_log ( " Handing out %d transcript(s) for storage " , log : self . log , type : . debug , coalescedContents . count )
83+ self . log . debug ( " Handing out \( coalescedContents . count ) transcript(s) for storage " )
8484
8585 self . storage. store ( coalescedContents, manifest: manifest)
8686 }
@@ -96,11 +96,11 @@ public final class TranscriptDownloader {
9696 case . success( let manifest) :
9797 self . currentManifest = manifest
9898
99- os_log ( " Transcript manifest downloaded. %d transcripts available. " , log : self . log , type : . debug , manifest . individual . count )
99+ self . log . debug ( " Transcript manifest downloaded. \( manifest . individual . count ) transcripts available. " )
100100
101101 self . processManifest ( manifest)
102102 case . failure( let error) :
103- os_log ( " Error downloading transcript manifest: %{public}@ " , log : self . log , type : . error, String ( describing : error ) )
103+ self . log . error ( " Error downloading transcript manifest: \( String ( describing : error) , privacy : . public ) " )
104104
105105 self . callCompletion ( )
106106 }
@@ -125,7 +125,7 @@ public final class TranscriptDownloader {
125125 guard let validIdentifiers = validSessionIdentifiers else { return true }
126126
127127 if !validIdentifiers. contains ( identifier) {
128- os_log ( " Ignoring %@ on manifest: not a session we know about. Maybe next time... " , log : self . log , type : . debug , identifier )
128+ self . log . debug ( " Ignoring \( identifier , privacy : . public ) on manifest: not a session we know about. Maybe next time..." )
129129
130130 return false
131131 } else {
@@ -139,35 +139,62 @@ public final class TranscriptDownloader {
139139 transcriptCountToLoad = validFeeds. count
140140 transcriptCountLoaded = 0
141141
142- validFeeds. forEach { feed in
143- downloadTranscriptIfNeeded ( identifier: feed. key, url: feed. value. url, etag: feed. value. etag)
142+ let transcripts : [ ( identifier: String , url: URL , status: CacheStatus ) ] = validFeeds. map { feed in
143+ let identifier = feed. key
144+ return ( identifier: identifier, url: feed. value. url, status: cacheStatus ( identifier: identifier, etag: feed. value. etag) )
145+ }
146+
147+ let transcriptsByStatus = Dictionary ( grouping: transcripts, by: \. status)
148+ let cached = transcriptsByStatus [ . match, default: [ ] ]
149+ let mismatched = transcriptsByStatus [ . etagMismatch, default: [ ] ]
150+ let noPreviousEtag = transcriptsByStatus [ . noPreviousEtag, default: [ ] ]
151+
152+ let cachedEtagMessage = cached. count == 0 ? " none " : noPreviousEtag. map ( \. identifier) . joined ( separator: " , " )
153+ let mismatchedMessage = mismatched. count == 0 ? " none " : mismatched. map ( \. identifier) . joined ( separator: " , " )
154+ let noPreviousEtagMessage = noPreviousEtag. count == 0 ? " none " : noPreviousEtag. map ( \. identifier) . joined ( separator: " , " )
155+
156+ log. trace (
157+ """
158+ Transcript Status:
159+ \t Cached: \( cachedEtagMessage)
160+ \t Missing etag: \( noPreviousEtagMessage)
161+ \t Mismatched etag: \( mismatchedMessage)
162+ """
163+ )
164+
165+ transcriptCountLoaded += cached. count
166+
167+ ( mismatched + noPreviousEtag) . forEach { ( identifier, url, _) in
168+ downloadTranscript ( identifier: identifier, url: url)
144169 }
145170 }
146171
147- private func downloadTranscriptIfNeeded( identifier: String , url: URL , etag: String ) {
148- if let previousEtag = storage. previousEtag ( for: identifier) {
149- guard etag != previousEtag else {
150- os_log ( " Cached transcript %@ still valid, skipping download " , log: self . log, type: . debug, identifier)
151- transcriptCountLoaded += 1
152- return
153- }
154- } else {
155- os_log ( " No previous etag for %@, assuming new and downloading " , log: self . log, type: . debug, identifier)
172+ enum CacheStatus {
173+ case etagMismatch, noPreviousEtag, match
174+ }
175+
176+ private func cacheStatus( identifier: String , etag: String ) -> CacheStatus {
177+ guard let previousEtag = storage. previousEtag ( for: identifier) else {
178+ return . noPreviousEtag
156179 }
157180
181+ return etag == previousEtag ? . match : . etagMismatch
182+ }
183+
184+ private func downloadTranscript( identifier: String , url: URL ) {
158185 loader. load ( from: url, decoder: { try JSONDecoder ( ) . decode ( TranscriptContent . self, from: $0) } ) { [ weak self] result in
159186 guard let self = self else { return }
160187
161188 defer { self . queue. async { self . transcriptCountLoaded += 1 } }
162189
163190 switch result {
164191 case . success( let content) :
165- os_log ( " Downloaded %@ " , log : self . log , type : . debug , identifier )
192+ self . log . debug ( " Downloaded \( identifier , privacy : . public ) " )
166193 self . queue. async { self . store ( content) }
167194 case . failure( let error) :
168195 self . queue. async { self . failedTranscriptIdentifiers. append ( identifier) }
169196
170- os_log ( " Failed to download %@: %{public}@ " , log : self . log , type : . error , identifier , String ( describing: error) )
197+ self . log . error ( " Failed to download \( identifier , privacy : . public ) : \( String ( describing: error) , privacy : . public ) " )
171198 }
172199 }
173200 }
0 commit comments