I was under the assumption that the entire reason updateasync exists was to prevent race conditions. This means that if UpdateAsync() and GetAsync() were called from two different servers simultaneously at the exact same time for the same key, if UpdateAsync was received first, it would run the supplied callback in its entirety, possibly changing the value of the key, and only then would the datastore run the GetAsync() call, and return the updated value. This means as the UpdateAsync() request is being processed for a particular key, the datastore doesn’t process any other requests at the same time until UpdateAsync() finishes.
To illustrate, if the requests are processed sequentially,
Originally, the key “money” = 100
Simultaneous UpdateAsync() and GetAsync() calls, but update is received first:
update sets “money” to 200
GetAsync() reads new value and returns 200
Processed in parallel
Originally, the key “money” = 100
Simultaneous UpdateAsync() and GetAsync() calls
Update sets “money” to 200. GetAsync() returns 100.
My confusion comes from the fact that UpdateAsync() can be called multiple times “In cases where another game server updated the key in the short timespan between retrieving the key’s current value and setting the key’s value”.
If requests are processed in sequentially, then no other game servers can “update the key in the short timespan”, since when UpdateAsync() is running for a particular key, no other get or set requests can modify the value for that key while update is doing its thing.
However, since other servers can indeed modify the value while UpdateAsync is running, that means that requests are processed in parallel which opens up a whole world of headaches, edge cases, and race conditions. That also means that in the scenario above, GetAsync would return the wrong value.