When using UpdateAsync, what things can you do to ensure data loss is kept at a minimum?

Currently, all I do in my UpdateAsync calls, is return a value, but can I do any kind of checks in the call to ensure that data is saved, and no data loss can ensue?

Example DataStore
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local PlayerData = DataStoreService:GetDataStore("PlayerData")

local closing = false β€” to know if the game is closing down

local function save(player)

    local dataHolder = player:WaitForChild("Data")
    local cash = dataHolder.Cash
    local rank = dataHolder.Rank
    
    local data = {
        Cash = cash.Value,
        Rank = rank.Value
    }

    local success, err = nil
    do

        local tries = 0

        repeat

        success, err = pcall(function) 
            PlayerData:UpdateAsync(player.UserId.."-data", function() 
                β€” can I do any additional checks here?
                return data
            end)
        end)
        tries += 1

        until success or tries > 3

    end

    if not success then
        warn("There was an error whilst saving", player.Name.."’s data!")
        warn("Error:", err)
    end

end

Players.PlayerAdded:Connect(function(player) 

    local dataHolder = player:WaitForChild("Data")
    local cash = dataHolder.Cash
    local rank = dataHolder.Rank

    local data = nil
    local success, err = nil
    do
        local tries = 0
        repeat

        success, err = pcall(function() 
            data = PlayerData:GetAsync(player.UserId.."-data")
        end)

        tries += 1
        until success or tries > 3

    end 


    if success then

        if data then

            cash.Value = data.Cash
            rank.Value = data.Rank

        else
            β€” set default values
        end

    else
        warn("There was an error whilst getting", player.Name.."’s data!")
        warn("Error:", err)

        player:Kick("You were kicked in an attempt to preserve your data!")
    end

end)

coroutine.wrap(function()

   while not closing do
        local autoSaveInterval = math.random(480,720) β€” 8-12 minutes
        for _, player in ipairs(Players:GetPlayers()) do
          coroutine.wrap(save)(player)
        end
        wait(autoSaveInterval)
   end

end)()

Players.PlayerRemoving:Connect(function() 
    if closing then β€” if the game is closing down, don’t save!
        return
    end

    save(player)

end)()

game:BindToClose(function() 
    closing = true

    for _, player in ipairs(Players:GetPlayers()) do
        coroutine.wrap(save)(player)
    end

end)
1 Like

Hi!

This post belongs on either #help-and-feedback:scripting-support or #help-and-feedback:code-review since you are asking for general feedback for actual code.