-
-
Notifications
You must be signed in to change notification settings - Fork 254
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
How to have performant fetches from a data stack without locking the main thread, but still allow reads concurrently with writes #471
Comments
The fetches are fine, but the error message indicates you are accessing the fetched objects' properties outside the main thread |
The error comes from this method in
So it looks like it is the actual fetch that is the problem. An example of a complete fetch where this error happens is:
|
@jimbengtsson92 I see, then it's exactly as the method says: fetches from DispatchQueue.global(qos: .utility).async {
withExtendedLifetime(dataStack.beginUnsafe()) { transaction in
let snapshots = try? transaction.fetchAll(...).compactMap({ $0.asSnapshot() })
completion(snapshots)
}
}
// code written by hand, so there might be compiler errors Just be careful not to access the relationship objects directly from the snapshots, as those need to be fetched again from either a Then when you need to edit the objects for these snapshots inside transactions, convert them back into the transaction instance by doing |
In our app all of our writes basically look like this:
and our reads like this:
With this setup we can achieve concurrent read and writes, but when performing a read this is locking the main thread. If I do not perform the fetch on the main thread I get a fatalError saying "Attempted to fetch from a 'CoreStore.DataStack' outside the main thread." error from CoreStore.
One way I have found we can do it to perform reads without locking the main thread is to use a transaction for these as well, like this:
With this approach I cannot however perform reads concurrently with writes, since they are both run on the same background serial queue that is created from the transaction. This is making the performance way worse in the cases when we are trying to do writes at around the same time as we do reads.
Do you, or anyone else, have any advice on how to do create fetches that do not lock the main thread, but can still run concurrently with writes?
The text was updated successfully, but these errors were encountered: