I just want the datastore to wait until other servers are not using that specific key and then it will update. The issue is it isn’t accurate a lot of the time. I tried but I just couldn’t find anything, maybe there is something but I haven’t found it.
local IsStudio = game:GetService("RunService"):IsStudio()
local DataStoreService = game:GetService("DataStoreService")
local MessagingService = game:GetService("MessagingService")
local DataStoreKey = DataStoreService:GetDataStore("GameVersion.1.0.2.4")
local ServerDebounce = false
local QueryofKeys = {}
local GameKey = tostring(game.JobId)
local function GetAsync(Key: string, ExpectedData)
if typeof(Key) ~= "string" then
return nil
elseif Key == "" then
return nil
end
repeat
task.wait()
until not ServerDebounce
local StartTick = tick()
local Success, Data
repeat
Success, Data = pcall(function()
return DataStoreKey:GetAsync(Key)
end)
task.wait()
until Success or tick() - StartTick > 5
if not Success then
warn("Failed to retrieve data for key: " .. Key)
return nil
end
return Data or ExpectedData
end
local function UpdateAsync(Key: string, Value, func: () -> ())
-- Wait for the debounce to clear
repeat
task.wait()
until not ServerDebounce
ServerDebounce = true
-- Subscribe to the key update messages
local CanProccess = true
local CanContinueServer = IsStudio
local TimeStarted = tick()
QueryofKeys[Key] = MessagingService:SubscribeAsync(Key, function(Data)
-- Check if the key is being processed by another server
Data = Data.Data
if Data[1] ~= GameKey and Data[2] == Key then
if QueryofKeys[Key] ~= nil then
QueryofKeys[Key]:Disconnect()
end
CanProccess = false
warn("Key is being processed by another server. Waiting...")
QueryofKeys[Key] = MessagingService:SubscribeAsync(Key, function()
if QueryofKeys[Key] ~= nil then
QueryofKeys[Key]:Disconnect()
end
CanProccess = true
end)
elseif Data[1] == GameKey and Data[2] == Key then
if QueryofKeys[Key] ~= nil then
QueryofKeys[Key]:Disconnect()
end
task.wait(tick() - TimeStarted)
CanContinueServer = true
end
end)
local CauseError = false
local DataSaveSuccess, DataSaveError = pcall(function()
-- Notify other servers that this server is processing the key
MessagingService:PublishAsync(Key, {GameKey, Key})
repeat
task.wait()
until CanContinueServer and CanProccess
-- Attempt to update the datastore
if func then
DataStoreKey:UpdateAsync(Key, function(CurrentData)
if func(CurrentData) then
CauseError = true
else
return Value
end
end)
else
DataStoreKey:SetAsync(Key, Value)
end
if CauseError then
error("Data already exists for key: " .. Key)
end
end)
-- Error handling for data saving
if not DataSaveSuccess then
warn("An error occurred while saving: " .. tostring(DataSaveError))
end
-- Cleanup: Disconnect and clear the subscription
if QueryofKeys[Key] then
QueryofKeys[Key]:Disconnect()
QueryofKeys[Key] = nil
end
MessagingService:PublishAsync(Key, {GameKey, Key})
-- Clear the debounce
ServerDebounce = false
return DataSaveSuccess
end
return {
UpdateAsync = UpdateAsync,
GetAsync = GetAsync,
}