foundrey
foundrey2h ago

StringKeyDictionary Resulting in two clients getting an entry on the same key

Hey guys! So we use a StringKeyDictionary for a task system whereby players all race to put an identical key (the task's nametag basically e.g. "round 1 / generateCourse") into the dictionary with a "claimModel" that they put their own client ID into However, when we've been testing and logging it appears like the transactional side of the dictionary is failing and: UniTask<bool> TryClaimTaskAsync(string taskKey, GSGTaskClaimModel claim) { var tcs = new UniTaskCompletionSource<bool>(); model.taskDictionary.Insert(taskKey, claim, success => tcs.TrySetResult(success)); return tcs.Task; } is coming back successful for multiple clients. The docs appear to say pretty specifically that this shouldn't be the case so I'm thinking we're missing something fundamental here. Any clarity on the system would be a huge help! Happy to provide any more context you guys need
3 Replies
kapa.ai
kapa.ai2h ago
Hi @foundrey. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- You're correct that the documentation for StringKeyDictionary states it is transactional: a model is not added to the collection until the server confirms the transaction, and if the key has been modified before your change reaches the server, your operation should be rejected. The relevant doc says:
"If any key has been modified before your change reaches the server, it will be rejected. It is up to your application to decide whether to retry the operation."
Reference: StringKeyDictionary Given this, your expectation is correct: only one client should be able to successfully insert a model for a given key if they race to claim it. If multiple clients are seeing success == true for the same key, this suggests one of the following: 1. Clients are not truly racing: There may be enough delay between the insertions that the server processes them sequentially, allowing each to succeed in turn (e.g., if the key is removed and then re-inserted quickly). 2. The key is not actually identical: Double-check that the taskKey string is byte-for-byte identical on all clients. 3. A bug or misunderstanding in the test setup: For example, if the dictionary is cleared or the key is removed between attempts, both clients could succeed if they are not truly simultaneous. 4. A possible bug in Normcore: If you have confirmed the above and are still seeing this, it may be worth reaching out to the Normcore team. What you can do: - Log the exact taskKey and timestamps for each insert attempt on all clients. - Ensure you are not removing or clearing the key between attempts. - Use the completionHandler's success value to only proceed if the insert was truly accepted. - If you continue to see this issue, provide a minimal reproducible example to the Normcore team. The docs are clear that the transactional guarantee should prevent multiple clients from successfully inserting on the same key at the same time, so if you are seeing otherwise, it is either a race condition not being triggered as you expect, or a deeper issue that may require Normcore support to investigate further
Reference: StringKeyDictionary
Collections Overview. Let me know if you can share more details or logs—I'm happy to help you dig deeper! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2h ago
<@719968242445058051> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
maxweisel
maxweisel2h ago
if any client receives the update from another client before it makes the change locally, it will succeed since the local state matches the server when the update was sent. how are you triggering the race between all clients at the same time?

Did you find this page helpful?