I have an async function that can be started from two location. Please note that within the getRecentMovies
, there is a Task {}
that makes an async
network call.
The first way to trigger the function is from:
.onChange(of: scenePhase) { newPhase in
guard newPhase == .active else {
return
}
vm.getRecentMovies()
}
so when the view loads into active, it will make an API request to a movies endpoint I have to refresh the data
the second way, is from a silent push notification that is handled in the AppDelegate
from within SwiftUI.
The issue I am having is that within the getRecentMovies()
, they make a request to both an API as well as getting data from CoreData that has been previously stored.
So if the user happens to open the app, at the same time that a silent push notification comes in, there the function will be running twice at the same time. This is causing issues for me with fetching the data from CoreData.
The issues is that one execution method fetches data, then execution continues, and the second method then fetches from core data.
So at this point, both functions have the same data from CoreData. Then function 1 completes, and resaves its data to CoreData. Then functions 2 finishes, and then saves data to CoreData, that is now invalid since there has now been another save.
I am wondering if there is a way to safely make sure that only one thread uses a function at a time. Since this functions is already being run in the background with the async
Task {}
dispatch, should I be using NSLock
s to make the execution pause.
If I did use NSLock
, function 1 would acquire a lock, then start executing, then function 2 would try and acquire a lock, but would be unable, so would pending until the lock is available.
Another option would be and try and cancel one of the tasks if I can detect that it is already running. But I am not sure how to do that.