kyle
kyle3mo ago

Expected behavior for two clients editing RTDict?

What's the expected behavior if two clients edit the same key for a RT dict at roughly the same time? Will both appear to succeed, and the request that happens to come 2nd will overwrite the first? Will two modelReplaced events be sent to listening clients?
5 Replies
kapa.ai
kapa.ai3mo ago
Hi @kyle. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- When two clients edit the same key in a RealtimeDictionary (RTDict) at roughly the same time, both changes will appear to succeed locally and will be applied instantly for each client. However, the server will ultimately determine which update is accepted based on the order in which it receives the changes. The last update received by the server will overwrite the previous one, following a "last-client-wins" approach. As for events, when a model is replaced under the same key, the modelReplaced event will fire for that key. If both clients make changes, and both updates are processed, you should expect two modelReplaced events to be sent to listening clients—one for each change as it is applied and then potentially rolled back or overwritten, depending on the server's resolution of the conflict. This behavior is described as follows:
RealtimeDictionary is a special model type that represents a dictionary of models. This collection can be modified by multiple clients simultaneously without introducing datastore conflicts. All updates are applied instantly and are rolled back if rejected by the server (due to ownership) ... A model is considered replaced (as opposed to removed and added) if a new model is added that overwrites an existing model under the same key.
RealtimeDictionary Reference Additionally, the general datastore update flow confirms that:
Updates to RealtimeModel objects appear to take effect immediately for the local client ... However, it is possible that the server will reject an update due to either ownership or Normcore Private plug-ins. When this happens, the server sends back the rejected update or a modified version of the state in the update. The datastore then rolls the data back or replaces it with the version transformed by the server. Change events then fire again to reflect the new values.
Room > Datastore So, in summary: - Both clients' changes will appear to succeed locally. - The server will resolve the conflict, and the last update received will win. - Two modelReplaced events may be fired, reflecting each change as it is applied and then potentially rolled back or overwritten. If you need transactional, versioned updates (where a change is only accepted if no one else has modified the key in the meantime), consider using StringKeyDictionary instead, which is transactional and will reject changes if the key has been modified before your change reaches the server.
Room > Collections ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@401595391549898754> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
kyle
kyleOP3mo ago
@Normal Team did someone on the team upvote, meaning this is accurate? sorry I can't tell if the above is accurate, would this work to check that an overwrite happened? not ideal but I'm curious if the model reference is expected to be up to date within an async function.
model.foo[0] = clientID;
await Task.Delay(2000)
// check that model.foo[0] == clientID
model.foo[0] = clientID;
await Task.Delay(2000)
// check that model.foo[0] == clientID
maxweisel
maxweisel3mo ago
yes that will work but maybe check out StringKeyDictionary, it’s atomic and has a callback that will be rejected if two clients try to change it at the same time
kyle
kyleOP3mo ago
ah okay, I'll check that out

Did you find this page helpful?