Skip to content

Commit

Permalink
Merge pull request #1173 from Infomaniak/fixImportNotCleared
Browse files Browse the repository at this point in the history
fix: Fix import folder taking a lot of space
  • Loading branch information
adrien-coye committed Apr 25, 2024
2 parents 426f939 + aded764 commit ff17985
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 73 deletions.
4 changes: 0 additions & 4 deletions kDriveCore/Data/DownloadQueue/DownloadQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,6 @@ public final class DownloadQueue: ParallelismHeuristicDelegate {
operationQueue.cancelAllOperations()
}

public func cancelRunningOperations() {
operationQueue.operations.filter(\.isExecuting).forEach { $0.cancel() }
}

/// Check if a file is been uploaded
///
/// Thread safe
Expand Down
20 changes: 20 additions & 0 deletions kDriveCore/Data/Models/Upload/UploadFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ public extension UploadFile {
}
}

/// Cleaning
public extension UploadFile {
/// Centralise error cleaning
func clearErrorsForRetry() {
Expand All @@ -328,6 +329,25 @@ public extension UploadFile {
// Reset retry count to default
maxRetryCount = UploadFile.defaultMaxRetryCount
}

/// Centralise source file cleaning
@discardableResult
func cleanSourceFileIfNeeded() -> Bool {
guard let path = pathURL,
shouldRemoveAfterUpload else {
return false
}

do {
try FileManager.default.removeItem(at: path)
assert(!FileManager.default.fileExists(atPath: path.path), "expecting the file to be removed")

return true

} catch {
return false
}
}
}

public extension [UploadFile] {
Expand Down
16 changes: 12 additions & 4 deletions kDriveCore/Data/UploadQueue/Operation/UploadOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,18 @@ public final class UploadOperation: AsynchronousOperation, UploadOperationable {
Log.uploadOperation("end file ufid:\(self.uploadFileId)")
}

if let path = file.pathURL,
file.shouldRemoveAfterUpload && file.uploadDate != nil {
Log.uploadOperation("Remove local file at path:\(path) ufid:\(self.uploadFileId)")
try? self.fileManager.removeItem(at: path)
// Remove source file if uploaded with success and required.
if file.uploadDate != nil {
if file.cleanSourceFileIfNeeded() {
Log.uploadOperation(
"Removed local file at path:\(String(describing: file.pathURL)) ufid:\(self.uploadFileId)"
)
}
} else {
Log.uploadOperation(
"Not removing local file, shouldRemove:\(file.shouldRemoveAfterUpload) at path:\(String(describing: file.pathURL)) ufid:\(self.uploadFileId)",
level: .warning
)
}

// If task is cancelled, remove it from list
Expand Down
71 changes: 7 additions & 64 deletions kDriveCore/Data/UploadQueue/Queue/UploadQueue+Queue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,60 +22,6 @@ import Foundation
import InfomaniakCore
import RealmSwift

public protocol UploadQueueable {
func getOperation(forUploadFileId uploadFileId: String) -> UploadOperationable?

/// Read database to enqueue all non finished upload tasks.
func rebuildUploadQueueFromObjectsInRealm(_ caller: StaticString)

/// Save an UploadFile in base and optionally enqueue the upload in main app
/// - Parameters:
/// - uploadFile: The upload file to be processed
/// - itemIdentifier: Optional item identifier
/// - addToQueue: Should we schedule the upload as well ?
/// - Returns: An UploadOperation if any
func saveToRealm(_ uploadFile: UploadFile, itemIdentifier: NSFileProviderItemIdentifier?, addToQueue: Bool)
-> UploadOperationable?

func suspendAllOperations()

func resumeAllOperations()

/// Wait for all (started or not) enqueued operations to finish.
func waitForCompletion(_ completionHandler: @escaping () -> Void)

// Retry to upload a specific file, this re-enqueue the task.
func retry(_ uploadFileId: String)

// Retry all uploads within a specified graph, this re-enqueue the tasks.
func retryAllOperations(withParent parentId: Int, userId: Int, driveId: Int)

func cancelAllOperations(withParent parentId: Int, userId: Int, driveId: Int)

/// Mark all running `UploadOperation` as rescheduled, and terminate gracefully
///
/// Takes more time than `cancel`, yet prefer it over a `cancel` for the sake of consistency.
/// Further uploads will start from the mail app
func rescheduleRunningOperations()

/// Cancel all running operations, regardless of state
func cancelRunningOperations()

/// Cancel an upload from an UploadFile. The UploadFile is removed and a matching operation is removed.
/// - Parameter file: the upload file id to cancel.
func cancel(uploadFile: UploadFile)

/// Cancel an upload from an UploadFile.id. The UploadFile is removed and a matching operation is removed.
/// - Parameter uploadFileId: the upload file id to cancel.
/// - Returns: true if fileId matched
func cancel(uploadFileId: String) -> Bool

/// Clean errors linked to any upload operation in base. Does not restart the operations.
///
/// Also make sure that UploadFiles initiated in FileManager will restart at next retry.
func cleanNetworkAndLocalErrorsForAllOperations()
}

// MARK: - Publish

extension UploadQueue: UploadQueueable {
Expand Down Expand Up @@ -253,16 +199,6 @@ extension UploadQueue: UploadQueueable {
}
}

public func cancelRunningOperations() {
Log.uploadQueue("cancelRunningOperations")
guard appContextService.context != .shareExtension else {
Log.uploadQueue("\(#function) disabled in ShareExtension", level: .error)
return
}

operationQueue.operations.filter(\.isExecuting).forEach { $0.cancel() }
}

@discardableResult
public func cancel(uploadFileId: String) -> Bool {
Log.uploadQueue("cancel uploadFileId:\(uploadFileId)")
Expand Down Expand Up @@ -293,6 +229,8 @@ extension UploadQueue: UploadQueueable {
return
}

uploadFile.cleanSourceFileIfNeeded()

let uploadFileId = uploadFile.id
let userId = uploadFile.userId
let parentId = uploadFile.parentDirectoryId
Expand Down Expand Up @@ -344,6 +282,11 @@ extension UploadQueue: UploadQueueable {
userId: userId,
driveId: driveId,
using: realm)

for file in uploadingFiles {
file.cleanSourceFileIfNeeded()
}

Log.uploadQueue("cancelAllOperations count:\(uploadingFiles.count) parentId:\(parentId)")
uploadingFilesIds = uploadingFiles.map(\.id)
Log.uploadQueue("cancelAllOperations IDS count:\(uploadingFilesIds.count) parentId:\(parentId)")
Expand Down
71 changes: 71 additions & 0 deletions kDriveCore/Data/UploadQueue/Queue/UploadQueueable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
Infomaniak kDrive - iOS App
Copyright (C) 2024 Infomaniak Network SA
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import FileProvider
import Foundation

public protocol UploadQueueable {
func getOperation(forUploadFileId uploadFileId: String) -> UploadOperationable?

/// Read database to enqueue all non finished upload tasks.
func rebuildUploadQueueFromObjectsInRealm(_ caller: StaticString)

/// Save an UploadFile in base and optionally enqueue the upload in main app
/// - Parameters:
/// - uploadFile: The upload file to be processed
/// - itemIdentifier: Optional item identifier
/// - addToQueue: Should we schedule the upload as well ?
/// - Returns: An UploadOperation if any
func saveToRealm(_ uploadFile: UploadFile, itemIdentifier: NSFileProviderItemIdentifier?, addToQueue: Bool)
-> UploadOperationable?

func suspendAllOperations()

func resumeAllOperations()

/// Wait for all (started or not) enqueued operations to finish.
func waitForCompletion(_ completionHandler: @escaping () -> Void)

// Retry to upload a specific file, this re-enqueue the task.
func retry(_ uploadFileId: String)

// Retry all uploads within a specified graph, this re-enqueue the tasks.
func retryAllOperations(withParent parentId: Int, userId: Int, driveId: Int)

/// Mark all running `UploadOperation` as rescheduled, and terminate gracefully
///
/// Takes more time than `cancel`, yet prefer it over a `cancel` for the sake of consistency.
/// Further uploads will start from the mail app
func rescheduleRunningOperations()

/// Clean errors linked to any upload operation in base. Does not restart the operations.
///
/// Also make sure that UploadFiles initiated in FileManager will restart at next retry.
func cleanNetworkAndLocalErrorsForAllOperations()

func cancelAllOperations(withParent parentId: Int, userId: Int, driveId: Int)

/// Cancel an upload from an UploadFile. The UploadFile is removed and a matching operation is removed.
/// - Parameter file: the upload file id to cancel.
func cancel(uploadFile: UploadFile)

/// Cancel an upload from an UploadFile.id. The UploadFile is removed and a matching operation is removed.
/// - Parameter uploadFileId: the upload file id to cancel.
/// - Returns: true if fileId matched
func cancel(uploadFileId: String) -> Bool
}
2 changes: 1 addition & 1 deletion kDriveFileProvider/FileProviderExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ final class FileProviderExtension: NSFileProviderExtension {
url: item.storageUrl,
name: item.filename,
conflictOption: .version,
shouldRemoveAfterUpload: false
shouldRemoveAfterUpload: true
)

var observationToken: ObservationToken?
Expand Down

0 comments on commit ff17985

Please sign in to comment.