Log in to vote

How would I use the DataStore to communicate between two servers?

Asked by
Vrakos 109
7 years ago

Could I use DataStoreService to communicate between two servers? If so, then how?

2 answers

Log in to vote
Answered by
jobro13 980 Moderation Voter
7 years ago

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)
        Data = {1}
    DataStore:SetAsync("TestKey", Data)
while wait(1) do
    local Key = DataStore:GetAsync("TestKey")

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!

I had already learnt. But this could help me improve. Thank you. :) Vrakos 109 — 7y
Log in to vote
Answered by 7 years ago

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:

DataStores are publicy released. Merely 2117 — 7y
Though you should note that you can serialize instances and save them. Also, do NOT use SetAsync. Instead, use UpdateAsync. Mention this for me to remove my downvote. TheLuaWeaver 301 — 7y
Uh, I think it is still in Beta and we all can't use it, or it is something I have not noticed it at all. FromLegoUniverse 264 — 7y
Oh Merely, I did not see your name for a minute. I think you have access to it because you are technically a developer, I am no where clsoe to a developer rank, still trying to learn things here and there. FromLegoUniverse 264 — 7y
View all comments (2 more)
I'm going to necrobump this message with some important updates. This information is incorrect. SetAsync does not respect the values which are on the roblox site currently, which will end up with data being corrupted if the two servers save to the same key at the same time. jobro13 980 — 7y
jobro13... I have no clue what on earth you just said. I will be rewriting my answer seeing I now know how it is used. FromLegoUniverse 264 — 7y

Answer this question