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

Use isolated(any) instead of Sendable for withMainSerialExecutor async operation #46

Merged

Conversation

jonduenas
Copy link
Contributor

When working with a MainActor isolated type inside the async operation closure for withMainSerialExecutor, the context was not being inferred as MainActor isolated. This can be easily demonstrated like this:

@MainActor
final class Foo {
    func sleep() async {
        try? await Task.sleep(for: .seconds(1))
    }
}

final class MainSerialExecutorActor: XCTestCase {
    @MainActor
    func testWithMainSerialExecutor() async {
        await withMainSerialExecutor {
            let foo = Foo() // ❌ Expression is 'async' but is not marked with 'await'
            await foo.sleep()
        }
    }
}

This only started happening after the change in #28.

@stephencelis pointed out on Slack that this can be resolved by using @isolated(any) instead of @Sendable on withMainSerialExecutor's operation closure. Locally this resolves the issue on my end.

@mercedesbunz
Copy link

I am also facing that issue when using https://github.com/pointfreeco/swift-concurrency-extras/releases/tag/1.2.0

Using your example @jonduenas

@MainActor
final class Foo {
	var didSleep: Bool = false

    func sleep() async {
        try? await Task.sleep(for: .seconds(1))
		didSleep = true
    }
}

final class MainSerialExecutorActor: XCTestCase {
    @MainActor
    func testWithMainSerialExecutor() async {
        await withMainSerialExecutor {
            let foo = await Foo() // adding `await`
            await foo.sleep()

			// assuming we don't need to do something to work with `Task.sleep`
			XCTAssertTrue(sut.didSleep, "Expected foo slept") // 🛑 - Main actor-isolated property 'didSleep' can not be referenced from a non-isolated autoclosure
        }
    }
}

I Added await for the construction to work around the issue and that feels ok to me but it starts to "hurt" when asserting.
Although that can be fixed by moving state access into a MainActor.run closure I guess.

Copy link
Member

@stephencelis stephencelis left a comment

Choose a reason for hiding this comment

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

Thanks!

@stephencelis stephencelis merged commit 163409e into pointfreeco:main Nov 11, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants