@ -35,8 +35,6 @@ public enum GarbageCollectionJob: JobExecutor {
}
let timestampNow : TimeInterval = Date ( ) . timeIntervalSince1970
var attachmentLocalRelativePaths : Set < String > = [ ]
var profileAvatarFilenames : Set < String > = [ ]
GRDBStorage . shared . writeAsync (
updates : { db in
@ -203,6 +201,19 @@ public enum GarbageCollectionJob: JobExecutor {
)
" " " )
}
} ,
completion : { _ , _ in
// D i s p a t c h a s y n c s o w e c a n s w a p f r o m t h e w r i t e q u e u e t o a r e a d o n e ( w e a r e d o n e w r i t i n g )
queue . async {
// R e t r i e v e a l i s t o f a l l v a l i d a t t a c h m n e t a n d a v a t a r f i l e p a t h s
struct FileInfo {
let attachmentLocalRelativePaths : Set < String >
let profileAvatarFilenames : Set < String >
}
let maybeFileInfo : FileInfo ? = GRDBStorage . shared . read { db -> FileInfo in
var attachmentLocalRelativePaths : Set < String > = [ ]
var profileAvatarFilenames : Set < String > = [ ]
// / O r p h a n e d a t t a c h m e n t f i l e s - a t t a c h m e n t f i l e s w h i c h d o n ' t h a v e a n a s s o c i a t e d r e c o r d i n t h e d a t a b a s e
if details . typesToCollect . contains ( . orphanedAttachmentFiles ) {
@ -225,12 +236,16 @@ public enum GarbageCollectionJob: JobExecutor {
. asRequest ( of : String . self )
. fetchSet ( db )
}
} ,
completion : { _ , result in
// I f a n y o f t h e a b o v e f a i l e d t h e n w e d o n ' t w a n t t o c o n t i n u e ( w e w o u l d e n d u p d e l e t i n g a l l f i l e s s i n c e
// n e i t h e r o f t h e a r r a y s w o u l d h a v e b e e n p o p u l a t e d c o r r e c t l y )
guard case . success = result else {
SNLog ( " [GarbageCollectionJob] Database queries failed, skipping file cleanup " )
return FileInfo (
attachmentLocalRelativePaths : attachmentLocalRelativePaths ,
profileAvatarFilenames : profileAvatarFilenames
)
}
// I f w e c o u l d n ' t g e t t h e f i l e l i s t s t h e n f a i l ( i n v a l i d s t a t e a n d d o n ' t w a n t t o d e l e t e a l l a t t a c h m e n t / p r o f i l e f i l e s )
guard let fileInfo : FileInfo = maybeFileInfo else {
failure ( job , StorageError . generic , false )
return
}
@ -261,7 +276,7 @@ public enum GarbageCollectionJob: JobExecutor {
. filter { path -> Bool in path . contains ( " / " ) }
. compactMap { path -> String ? in path . components ( separatedBy : " / " ) . first }
let orphanedAttachmentFiles : Set < String > = allAttachmentFilePaths
. subtracting ( attachmentLocalRelativePaths )
. subtracting ( fileInfo . attachmentLocalRelativePaths )
. subtracting ( directoryNamesContainingContent )
orphanedAttachmentFiles . forEach { filepath in
@ -285,7 +300,7 @@ public enum GarbageCollectionJob: JobExecutor {
. defaulting ( to : [ ] )
. asSet ( )
let orphanedAvatarFiles : Set < String > = allAvatarProfileFilenames
. subtracting ( profileAvatarFilenames )
. subtracting ( fileInfo . profileAvatarFilenames )
orphanedAvatarFiles . forEach { filename in
// W e d o n ' t w a n t a s i n g l e d e l e t i o n f a i l u r e t o b l o c k d e l e t i o n o f t h e o t h e r f i l e s s o t r y
@ -307,6 +322,7 @@ public enum GarbageCollectionJob: JobExecutor {
success ( job , false )
}
}
)
}
}