Open cmelchior opened 1 year ago
We can probably use the existing sync progress information for this. We defer sending any upload messages until the initial download is complete, so progress_upload_client_version == 0
might work as a check to see if the initial download has ever completed.
That check is not 100% reliable. Download completion is marked by a MARK message, which usually is received before sending any UPLOAD message (it will also have to be ACK'd to persist between sessions). If the app is closed immediately after the MARK message is received, next time the app starts it will open the realm using async open (instead of normally). But I think that's acceptable.
I think it's fine if we mark an async open as successfully completed very slightly later in the process than is strictly correct. Is it guaranteed that we will always eventually set the upload version even if there's no local writes, though?
There is going to be at least one write for the schema, so we can leverage that. IIUC opening a realm with no schema is not very common. EDIT: We could rely on the schema version instead (is set at the end of async open), but the issue mentioned below still holds.
Side note: if we only want to use async open once when the realm is created, it will conflict with schema migrations where we require async open for phase one and the realm will most likely already exist.
No write will be performed to initialize the schema if it's an exact match for what the server sent us, as it'll already be initialized.
Right. We can probably find a different way. The issue with this kind of solution is that it requires opening the realm to read some data so we know how to open the realm 🙂
Async Open of synchronized Realms is an optimization that allows us to download and bootstrap a Realm the first time it is opened. Unfortunately, it behaves in a way that makes it hard for SDKs to use.
Some SDKs (at least Java, Kotlin, and Swift) use the presence of a Realm file as an indicator of whether or not to actually use async open, but this check doesn't really work if there is a crash while async open is running and the app is restarted since it seems that a Realm file will be created as soon as async open starts. This results in the following sequence of events:
Wanted solution: Some way for SDKs to check if Async Open was interrupted and restart it if possible.
Suggestions (others probably exist):
Workaround: Currently, we advise users on Android to track the state in
SharedPreferences
, i.e. set a flag when opening the Realm for the first time, and if the app is restarted with this flag set, delete the Realm file and restart the download, but obviously, this not only requires a small amount of boilerplate, it can also cause the same data to be downloaded multiple times.