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

SDKS-3458 Swift6 adoption + concurrency check #6

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from

Conversation

jeyanthanperiyasamy
Copy link
Contributor

@jeyanthanperiyasamy jeyanthanperiyasamy commented Oct 24, 2024

JIRA Ticket

SDKS-3458 DaVinci Swift 6.0 adoption (concurrency check)

Description

Reduce the reliance on traditional classes as part of our commitment to improve compatibility with Swift 6 concurrency. This initial commit marks a step in that direction.

To achieve better thread safety, we should prioritize using actor, struct, and final class more frequently, while minimizing inheritance where possible. Embracing a concurrency-first pattern will help us leverage Swift’s capabilities more effectively.

We should continuously identify opportunities to decrease class usage, ensuring our code is both safe and efficient in a concurrent environment.

Checklist:

  • I ran all unit tests and they pass
  • I added test case coverage for my changes

@spetrov spetrov changed the title Sdks 3458 SDKS-3458 Swift6 adoption + concurrency check Oct 31, 2024
Copy link
Contributor

@spetrov spetrov left a comment

Choose a reason for hiding this comment

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

LGTM!


import Foundation

public struct SendableAny: @unchecked Sendable {
Copy link

@rodrigoareis rodrigoareis Nov 5, 2024

Choose a reason for hiding this comment

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

Add doc to the struct and public methods

Copy link

@rodrigoareis rodrigoareis left a comment

Choose a reason for hiding this comment

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

Looks good to me. Just a minor comment to be addressed.

@jeyanthanperiyasamy jeyanthanperiyasamy force-pushed the SDKS-3458 branch 3 times, most recently from 41794d3 to 9c6721f Compare November 6, 2024 05:46
Copy link

@witrisna witrisna left a comment

Choose a reason for hiding this comment

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

Most of my comments are just question

let components = form[Constants.components] as? [String: Any],
let fields = components[Constants.fields] as? [[String: Any]] {
collectors = CollectorFactory().collector(from: fields)
actor Form {
Copy link

Choose a reason for hiding this comment

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

There is not mutable state in Form, any reason we need to define it as actor?

Copy link
Contributor Author

@jeyanthanperiyasamy jeyanthanperiyasamy Nov 6, 2024

Choose a reason for hiding this comment

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

Form can be a struct ... we generally reduce using classes. For this scenario actor is not required. i will change this.

public var key: String = ""
public var label: String = ""
public var value: String = ""
open class FieldCollector: Collector, @unchecked Sendable {
Copy link

Choose a reason for hiding this comment

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

Looks like you handle concurrent update of attributes, why define as unchecked?

Copy link
Contributor Author

@jeyanthanperiyasamy jeyanthanperiyasamy Nov 6, 2024

Choose a reason for hiding this comment

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

In Swift 6, this code won't compile as-is, because the compiler will error:
"Non-final class 'FieldCollector' cannot conform to 'Sendable'".

To resolve this, we need to instruct the compiler to skip the compatibility check by explicitly marking the conformance as unchecked. This can be done using @unchecked Sendable,


func reset() {
collectors.removeAll()
public actor CollectorFactory {
Copy link

Choose a reason for hiding this comment

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

Is this a Singleton?

Copy link
Contributor Author

@jeyanthanperiyasamy jeyanthanperiyasamy Nov 6, 2024

Choose a reason for hiding this comment

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

yes, CollectorFactory.shared is the usage.

So customer will have to call like to add custom callback ..
await CollectorFactory.shared.register(type: collector:)

@@ -13,7 +13,7 @@ import Foundation
import PingOidc
import PingOrchestrate

public class OidcModule {
public actor OidcModule {
Copy link

Choose a reason for hiding this comment

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

There is no state in OidcModule, why define it as actor?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

by default static property in classes are not thread safe. so compiler will throw error

Static property 'config' is not concurrency-safe because non-'Sendable' type 'Module<OidcClientConfig>' may have shared mutable state

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me think about this in another way

@@ -10,7 +10,7 @@


/// Class for an OIDC User
public class OidcUser: User {
public final class OidcUser: User, @unchecked Sendable {
Copy link

Choose a reason for hiding this comment

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

Can this define as Actor?

Copy link
Contributor Author

@jeyanthanperiyasamy jeyanthanperiyasamy Nov 6, 2024

Choose a reason for hiding this comment

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

To convert this to actor , we need to convert lot of other code to be sendable like AgentDelegate, OidcClient etc to be sendable .

Since this is an first step for swift 6. We should continuously seek opportunities to reduce class usage as much as possible and use actor/struct . so we are better compatibile with Swift 6 concurrency

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants