OAuthenticator icon indicating copy to clipboard operation
OAuthenticator copied to clipboard

Sendable issue on Linux

Open 0xTim opened this issue 2 months ago • 1 comments

So I'm not sure the best way forward for this one - but summary:

We're using the OAuthentication library as part of a package that's consumed by multiple apps and multiple platforms (Apple and Linux). We're having an issue using the package when compiling on Linux with the following code:

let config = Authenticator.Configuration(
    appCredentials: appCredentials,
    loginStorage: loginStorage,
    tokenHandling: tokenHandling,
    userAuthenticator: userAuthenticator,
    authenticationStatusHandler: authenticationStatusHandler
)

let authenticator = Authenticator(config: config)

That produces the error:

error: sending 'config' risks causing data races [#SendingRisksDataRace]
338 |         )
339 | 
340 |         let authenticator = Authenticator(config: config)
    |                             |- error: sending 'config' risks causing data races [#SendingRisksDataRace]
    |                             `- note: sending 'config' to actor-isolated initializer 'init(config:urlLoader:)' risks causing data races between actor-isolated and local nonisolated uses

Now the error makes sense, since Configuration is not Sendable and the status handler makes it awkward to be safe. I'm not sure why this compiles fine on macOS, I feel like I'm missing an isolation trick somewhere.

The workaround I've come up with so far is to make Configuration Sendable, but that can require handling the status with some kind of lock/mutex. It's definitely workable (and makes it safe) but can be difficult to use.

Do you have any insight as to why this is failing on Linux to start? I'm happy to submit a patch too

0xTim avatar Sep 30 '25 11:09 0xTim

Yeah, I made this library before I knew exactly what I was doing. Getting it to be correct was a bit of work, and this was one of the trickier areas.

The AuthenticationStatusHandler type is not marked @Sendable. It technically doesn't need it, as long as it can be transferred when passing into that init. And because that works on macOS but not linux, my guess is that function is @Sendable on macOS but not on Linux. MainActor could possibly be involved here.

Does that seem like it could explain the difference?

mattmassicotte avatar Sep 30 '25 12:09 mattmassicotte