Realm Object Server Sync Production Usage


#1

Open question to anyone using Realm Object Server sync in production. This is tangentially related to some issues I started to see while exploring what was going on with https://forums.realm.io/t/unsupported-instruction-error-on-swift-asyncopen/950/5 .

I had neglected to notice while working on an ROS prototype that destructive migrations were essentially not supported with Realm Object Server ( or certainly heavily advised against, as per https://realm.io/docs/swift/latest/#syncing-migrations ). The instructions on that documentation page lead me to believe that the following things are true for Realm Object Server / Realm Platform:

  1. With Realm Object Server, schema changes are very, very important to detect as they can prevent clients from initializing correctly. I say “schema changes” in the global sense, that is schema changes as broadcast by the ROS ( which I assume is an equal peer with the clients in distributed Realm ) and schema changes as implied by clients connecting to ROS.

  2. With Realm Object Server, it’s implied that connecting clients should manage and version their access to collections themselves, in order to prevent a schema change from preventing them from moving forward. ( using the advice from the linked documentation page, namely:

    Since synced Realms don’t support migration blocks, destructive changes for a migration—changing a primary key, changing field types of existing fields (while keeping the same name), or changing a property from optional to required or vice-versa—need to be handled in a different way. Create a new synchronized Realm with the new schema, and copy data from the old Realm to the new Realm:

  3. Synchronized Realms can’t be opened in Read Only mode, which means that the schema is always mutable by any client at any time. Which means that you have to be extremely disciplined about following the advice in (2), due to the fact that any schema change can prevent any/all other clients from opening a Realm cleanly.

  4. Schemas are (by nature of how they’re determined by N separate platforms), not really deterministic. eg, there’s no simple way for me to state that for any given Realm configuration on a platform, it will be identical to the Realm configuration on another platform. Or put another way, there’s no way for me to issue this deterministically across N platforms or versions:

    CREATE realm FOO
    ALTER realm FOO ( name STRING, counter INT )
    

since the given Realm configuration for a platform is inferred by how Realm detects properties on a given class.

Are all these facts true in production? Does anyone using ROS in production run into these things if so, or are concerns / issues like this largely not important for common ROS usage?


#2

Destructive schema changes are forbidden explicitly to avoid issues with older clients. So there should be no way for a schema change to prevent a (previously working) app to fail to start/initialize correctly. Can you elaborate on what problems you’re concerned about in 1? I’d go over all 4 points but I feel that once we clear up 1, the rest will be turn out to be variations of that :slight_smile:


#3

Are they outbound forbidden? Or inbound forbidden? My reading of the documentation suggested that a client can cause a destructive schema change to be issued to the ROS, just that it was not advised (to summarize what I thought the documentation was saying, it seemed to state that “destructive changes are dangerous, version your collection names instead” ) Anecdotally, as of that Realm Swift forums link I posted above, i was definitely seeing what I assume were destructive migrations ( RemoveProperty ) being issued to a new client and preventing the client from starting cleanly in an ROS environment.


#4

I’m not sure I understand what inbound and outbound means in this context. Basically, if you have a Realm with a single class Foo and a single property Bar of type string. Your app happily syncs with ROS. A week later, you create a new version of the app, where Bar is now int. If your new version tries to open the “old” Realm, it’ll get an error and ROS will terminate the connection. So all old versions of your app will still work, but your new version will not. Hopefully you’ll notice that during development though. However, if your new app creates the Realm first and an older version of the app tries to connect, the old version will fail (as ROS handles them on a first come-first serve basis). But in no scenario would an attempted destructive change result in an app that has previously worked to stop working.

I’m not familiar with the Swift SDK and what is the reason for the error you’re getting there, but removing a property is not a destructive change - the property still exists on ROS and all clients that have that property in their schema. For the client that “removed” the property, it’s just hidden. You can think of it as the opposite of adding a property. Again, if the first version of your app doesn’t have the property Bar and the second version of your app adds it, for everyone involved, that’s equivalent to first version having the property and second version removing it (again, ROS isn’t aware or cares about app versions).