Could I use DataStoreService to communicate between two servers? If so, then how?
This is an interesting question, which I couldn't answer until now. I had no idea how roblox would handle conflicting data. I'll explain this with an example.
Let's say we have two servers. Server A and Server B. We are using this data store:
local DataStoreService = game:GetService("DataStoreService") local DataStore = DataStoreService:GetDataStore("TestData")
Let's see what happens if we use GetAsync and SetAsync.
local DataStoreService = game:GetService("DataStoreService") local DataStore = DataStoreService:GetDataStore("TestData") local function Update(Key) local Data if Key then Data = table.insert(Data, Data[#Data] + 1) else Data = {1} end DataStore:SetAsync("TestKey", Data) end while wait(1) do local Key = DataStore:GetAsync("TestKey") Update(Key) end
At first glance, this seems to work. If everything works correctly, we should get a table in which the table index is also the table key. In other words: table[index] == index should be true.
However, this will conflict. I'll try to explain why. The GetAsync
function will cache data. In other words: what this method returns does not necessarily be the real data currently stored on the servers. SetAsync
breaks this cache.
Let's loop through this and lets assume the keys cache for AT LEAST 10 seconds. This example only shows that data will be lost and not that data will corrupt. However, this example illustrates that data corruption is also possible.
Server1 calls the Update function. The key is nil. The table saved is now {1}. Nothing wrong here. Server2 calls the Update function. The key is {1} (this is the first call, so we can be almost sure this is the real data). It will now set the data to {1,2}. Server1 calls the update function. The key is {1} (the data is cached). The table saved is now {1,2}, while it should be {1,2,3}.
Note: This 10-second cache limit is real.
As you can see, data is lost. So, you can't use this to communicate between two servers, as data will be lost, or, in worse cases: will be corrupted.
But how should you possibly solve this then..? The answer has been designed by the roblox developers themselves: The UpdateAsync
function. This UpdateAsync will do a job which you can't do: make sure that data is not being lost. (You can't do this yourself as you cannot send Http requests to the roblox servers directly, and you cannot use GetAsync to make sure that the data is correct, as this is cached.)
How does UpdateAsync works? It takes two arguments: the key to update and the update function. This update function is important. It receives the old value (either in the cache or returned by the roblox servers) and it must return a new value which should be saved.
How does this mechanism work?
The UpdateAsync function is run. The oldValue received by the function and the newValue returned by the function are posted to the roblox servers. The roblox servers will perform a check: Is the oldValue the current value into the store? If this is the case, the data gets saved. If this is NOT the case however, then data will probably be lost if this is saved. The roblox servers will notify the calling server that the data is not correct and it will re-run the UpdateAsync function, but now with the value currently into the data store. The cycle repeats. The oldValue and newValue are posted to the website and the check repeats. As you can imagine, there is a small chance that the oldValue is not correct (because another server has saved data to the servers). In that case, the cycle will repeat, until the oldValue is finally the same as the value the roblox servers have saved.
So, you need to use UpdateAsync
to communicate between two or more servers. You are using the same keys, so this is necessary.
There are a lot of uses for this. Think of cross-server chat, server management (how much servers are online? who are in the servers?). Especially cross-server chat seems (for me) to be impossible if you don't use UpdateAsync.
Spread the world!
Yes, as long as they are in the same game universe. It is similar to data persistence. But the methods are different. You would use :GetAsync(String) and :SetAsync(String,Value) or :UpdateAsync(String,Value) [More Recommended], and the value can be anything but Instances at the moment.
This is a very basic example: game:GetService("DataStoreService"):GetDataStore("Number"):SetAsync("EpicNumber",9001) print(game:GetService("DataStoreService"):GetDataStore("Number"):SetAsync("EpicNumber"))
It will print 9001. If you need an example to work off of, I have an open sourced leaderstats script that works like the old one, but works between places: http://www.roblox.com/DataStoreService-Leaderstats-Levels-Exp-Coins-item?id=148583818