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

RDART-1020: Fix writeAsync behaviour #1666

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

RDART-1020: Fix writeAsync behaviour #1666

wants to merge 5 commits into from

Conversation

nielsenko
Copy link
Contributor

@nielsenko nielsenko commented May 6, 2024

Calling Realm.writeAsync with an async callback is currently broken, since the callback is not awaited, and not passed as a FutureOr<T> Function().

The first commit adds tests thats illustrates a number of issues with the current approach, and the second fixes them.

We could consider detecting re-entrancy, and either throw an exception, or simply allow it by participating in the calling transaction, but this is not handled by the current PR.

Fixes: #1667

@nielsenko nielsenko requested a review from nirinchev May 6, 2024 16:40
@cla-bot cla-bot bot added the cla: yes label May 6, 2024
@nielsenko nielsenko changed the title Fix writeAsync behaviour RDART-1020: Fix writeAsync behaviour May 6, 2024
@nielsenko nielsenko marked this pull request as ready for review May 6, 2024 17:01
Copy link
Member

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

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

I don't think we should do that. We're intentionally guiding people toward using the sync API because holding the write lock for extended periods of time is an antipattern and can result in app freezes in multithreaded/process scenarios and can usually be avoided by doing the async calls before entering the write transaction.

My suggestion would be to instead check if T is a future and log a warning or even error out.

@nielsenko
Copy link
Contributor Author

I don't think we should do that. We're intentionally guiding people toward using the sync API because holding the write lock for extended periods of time is an antipattern and can result in app freezes in multithreaded/process scenarios and can usually be avoided by doing the async calls before entering the write transaction.

My suggestion would be to instead check if T is a future and log a warning or even error out.

I disagree.

We already expose beginWriteTransaction and friends, so users have all the foot-guns they need available already. writeAsync is just a 10-line wrapper around these.

If we force people to not use async callbacks in writeAsync they will just start using those APIs directly. I think it is much better to make writeAsync behave sane, and just keep warning against long running transactions. We can definitely ensure that writeAsync never blocks, as long as the callback don't.

We should however make such a check in write. Today you can pass an async callback unhindered to write, which affords no sane semantics.

@nielsenko nielsenko requested a review from nirinchev May 6, 2024 19:42
@nirinchev
Copy link
Member

Yes, I know it's not difficult to do it and I don't think we should be super actively preventing people from doing it, but I want to make it harder for them to shoot themselves in the foot. The writeAsync API is the default one people are likely to use, so if that has a future as its argument, it'll imply that we condone or even encourage doing async work in the callback. Instead, my preference would be to throw in case you pass in a future and if someone complains, explain they could achieve the same with the begin/commit API. Happy to bounce ideas about it at some point this week though as it's mostly a cautious preference rather than a strong conviction against it.

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

Successfully merging this pull request may close these issues.

Realm.writeAsync do not handle async callbacks correctly
2 participants