Skip to content

Commit 5117344

Browse files
committed
Work in progress: Sendable
Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
1 parent af54584 commit 5117344

5 files changed

Lines changed: 19 additions & 29 deletions

File tree

Sources/NextcloudFileProviderKit/Enumeration/RemoteChangeObserver.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ extension RemoteChangeObserver: URLSessionWebSocketDelegate {
397397
// MARK: - NextcloudKitDelegate methods
398398

399399
extension RemoteChangeObserver: NextcloudKitDelegate {
400-
nonisolated public func authenticationChallenge(_: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
400+
nonisolated public func authenticationChallenge(_: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @Sendable @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
401401
Task { [weak self] in
402402
guard let self else {
403403
return
@@ -411,12 +411,7 @@ extension RemoteChangeObserver: NextcloudKitDelegate {
411411
logger.debug("Received auth challenge with method: \(authMethod)")
412412

413413
if authMethod == NSURLAuthenticationMethodHTTPBasic {
414-
let credential = URLCredential(
415-
user: account.username,
416-
password: account.password,
417-
persistence: .forSession
418-
)
419-
414+
let credential = URLCredential(user: account.username, password: account.password, persistence: .forSession)
420415
completionHandler(.useCredential, credential)
421416
} else if authMethod == NSURLAuthenticationMethodServerTrust {
422417
// TODO: Validate the server trust

Sources/NextcloudFileProviderKit/Extensions/RandomAccessCollection+Extensions.swift

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,21 @@ extension RandomAccessCollection {
3131
}
3232

3333
/// Performs an asynchronous `forEach` operation on the collection in concurrent chunks.
34-
func concurrentChunkedForEach(into size: Int = defaultChunkSize, operation: @escaping (Element) async -> Void) async {
34+
func concurrentChunkedForEach(into size: Int = defaultChunkSize, operation: @escaping @Sendable (Element) async -> Void) async where Element: Sendable {
3535
await withTaskGroup(of: Void.self) { group in
3636
for chunk in chunked(into: size) {
37-
let chunkArray = Array(chunk) // Convert to Array to ensure Sendable
38-
39-
group.addTask {
37+
let chunkArray = Array(chunk)
38+
group.addTask(operation: { @Sendable in
4039
for element in chunkArray {
4140
await operation(element)
4241
}
43-
}
42+
})
4443
}
4544
}
4645
}
4746

4847
/// Performs an asynchronous `compactMap` operation on the collection in concurrent chunks.
49-
func concurrentChunkedCompactMap<T>(into size: Int = defaultChunkSize, transform: @escaping (Element) throws -> T?) async throws -> [T] where T: Sendable {
48+
func concurrentChunkedCompactMap<T>(into size: Int = defaultChunkSize, transform: @escaping @Sendable (Element) throws -> T?) async throws -> [T] where T: Sendable, Element: Sendable {
5049
try await withThrowingTaskGroup(of: [T].self) { group in
5150
var results = [T]()
5251
// Reserving capacity is still a good optimization, though we can't know the exact final count.
@@ -55,11 +54,11 @@ extension RandomAccessCollection {
5554
for chunk in chunked(into: size) {
5655
let chunkArray = Array(chunk) // Convert to Array to ensure Sendable
5756

58-
group.addTask {
57+
group.addTask(operation: { @Sendable in
5958
try chunkArray.compactMap {
6059
try transform($0)
6160
}
62-
}
61+
})
6362
}
6463

6564
for try await chunkResult in group {

Sources/NextcloudFileProviderKit/Interface/FileProviderChangeNotificationInterface.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
22
// SPDX-License-Identifier: GPL-2.0-or-later
33

4-
import FileProvider
4+
@preconcurrency import FileProvider
55
import Foundation
66

7-
public class FileProviderChangeNotificationInterface: ChangeNotificationInterface {
7+
public final class FileProviderChangeNotificationInterface: ChangeNotificationInterface {
88
let domain: NSFileProviderDomain
99
let logger: FileProviderLogger
1010

Sources/NextcloudFileProviderKit/Interface/RemoteInterface.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ public extension RemoteInterface {
162162
) async -> (account: String, capabilities: Capabilities?, data: Data?, error: NKError) {
163163
let ncKitAccount = account.ncKitAccount
164164
await RetrievedCapabilitiesActor.shared.awaitFetchCompletion(forAccount: ncKitAccount)
165-
guard let lastRetrieval = await RetrievedCapabilitiesActor.shared.data[ncKitAccount],
166-
lastRetrieval.retrievedAt.timeIntervalSince(Date()) > -CapabilitiesFetchInterval
165+
guard let lastRetrieval = await RetrievedCapabilitiesActor.shared.getCapabilities(for: ncKitAccount), lastRetrieval.retrievedAt.timeIntervalSince(Date()) > -CapabilitiesFetchInterval
167166
else {
168167
return await fetchCapabilities(
169168
account: account, options: options, taskHandler: taskHandler

Sources/NextcloudFileProviderKit/Utilities/RetrievedCapabilitiesActor.swift

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,18 @@ import NextcloudCapabilitiesKit
77
let CapabilitiesFetchInterval: TimeInterval = 30 * 60 // 30mins
88

99
actor RetrievedCapabilitiesActor {
10-
static let shared: RetrievedCapabilitiesActor = {
11-
let instance = RetrievedCapabilitiesActor()
12-
return instance
13-
}()
10+
static let shared = RetrievedCapabilitiesActor()
1411

1512
var ongoingFetches: Set<String> = []
16-
var data: [String: (capabilities: Capabilities, retrievedAt: Date)] = [:]
13+
private var data: [String: (capabilities: Capabilities, retrievedAt: Date)] = [:]
1714

1815
private var ongoingFetchContinuations: [String: [CheckedContinuation<Void, Never>]] = [:]
1916

20-
func setCapabilities(
21-
forAccount account: String,
22-
capabilities: Capabilities,
23-
retrievedAt: Date = Date()
24-
) {
17+
func getCapabilities(for account: String) -> (capabilities: Capabilities, retrievedAt: Date)? {
18+
data[account]
19+
}
20+
21+
func setCapabilities(forAccount account: String, capabilities: Capabilities, retrievedAt: Date = Date()) {
2522
data[account] = (capabilities: capabilities, retrievedAt: retrievedAt)
2623
}
2724

0 commit comments

Comments
 (0)