Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Core] Make storage class conform to Sendable and subsequent changes #13939

Merged
merged 8 commits into from
Oct 30, 2024

Conversation

ncooke3
Copy link
Member

@ncooke3 ncooke3 commented Oct 21, 2024

Addresses two more Swift 6 errors (with more changes to address the errors from that resulted from the initial changes):

  • 💥 Capture of 'self' with non-sendable type 'HeartbeatStorage' in a @Sendable closure
    let oldHeartbeatsBundle = try? load(from: storage)

Needed to conform HeartbeatStorage class to Sendable (requirements).

The problem was the second requirement: Contain only stored properties that are immutable and sendable

private let storage: any Storage // Also needed to be made Sendable

Jumping into the Storage.swift file, the two conforming classes, FileStorage and UserDefaultsStorage, wrapped Foundation APIs FileManager and UserDefaults, respectively. Both Foundation APIs are not Sendable and it would be risky for us to add such conformance. So, I followed the approach discussed in https://forums.developer.apple.com/forums/thread/757527 to remove them as stored properties and instead initialize them in each context they are needed. It's not great, but avoids having to use unchecked Sendable.

  • 💥 Capture of 'transform' with non-sendable type '(HeartbeatsBundle?) -> HeartbeatsBundle?' in a @Sendable closure

This is straightforward– DispatchQueue.async takes an Sendable closure so we need to pass it one. This bubbled upwards to the _Objc_HeartbeatController level (this is the public API level used by FirebaseCore module). I re-generated the FirebaseCoreInternal-Swift.h and did not see any difference to the asyncFlush API's signature when adding the @Sendable attribute.

FirebaseCoreInternal and its test suite builds with language mode set to Swift 6. 🎉

#no-changelog

@ncooke3 ncooke3 marked this pull request as draft October 22, 2024 14:02
@ncooke3 ncooke3 changed the title [Core] Make storage class conform to Sendable [Core] Make storage class conform to Sendable and subsequent changes Oct 28, 2024
@ncooke3 ncooke3 marked this pull request as ready for review October 28, 2024 17:10
Copy link
Member

@paulb777 paulb777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to add Swift 6 compliance testing in CI?

Copy link
Contributor

@andrewheard andrewheard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Nick!

Jumping into the Storage.swift file, the two conforming classes, FileStorage and UserDefaultsStorage, wrapped Foundation APIs FileManager and UserDefaults, respectively. Both Foundation APIs are not Sendable and it would be risky for us to add such conformance. So, I followed the approach discussed in forums.developer.apple.com/forums/thread/757527 to remove them as stored properties and instead initialize them in each context they are needed. It's not great, but avoids having to use unchecked Sendable.

This looks very reasonable to me. I don't think calling, e.g., FileManager.default should be expensive at all. It makes testing slightly more difficult since we can't inject a fake but we weren't doing it for FileManager anyway and you worked around it for UserDefaults. LGTM.

@ncooke3 ncooke3 merged commit 45a5a4d into main Oct 30, 2024
62 checks passed
@ncooke3 ncooke3 deleted the nc/cs62 branch October 30, 2024 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants