Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

If I make my datasave script like this will it save for many players without queue full?

Asked by 5 years ago
Yuan.Changed:Connect(function()
    wait(10)
    datast1:SetAsync(plr.UserId, Yuan.Value)
    print('Data has been saved')
    repeat

    until game.Players.PlayerRemoving:Connect(function()

    end)
end)

1 answer

Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

From chatting with you I now suspect that Yuan changes whenever you are in contact with a part (via a Touched event). Touched events can trigger many times per second -- attempting to call SetAsync every time that that happens is going to have throttling problems regardless of if you wait 10 seconds before doing it. Importantly, note that every time an event occurs, it will start a new coroutine (also known as 'thread') to run your function (you might think of it like a "copy" or "instance"); they can all wait for 10 seconds simultaneously.

Note that your repeat until loop is not good. You only want to use repeat until if you want to repeat something until a condition is true (but you aren't repeating anything -- not even a 'wait()' command, which would be required to prevent Roblox from freezing in the event that the condition you are checking in the 'until' part is false/nil). I suspect you are trying to say (in English) "wait until the player has left before trying to save again", but all that code does is create a memory leak: the Connect function returns a Connection object (which will be considered true by the repeat loop causing it stop looping, which is why your game didn't freeze up). Now, you don't store this connection in a variable, but it's still remembered by the event you connected to, and thus will stay in memory even though you don't need it.

To fix this, the plan I recommend is to allow only one thread to save at a time and to allow one more thread to wait for the first one to save (and wait for the 10 second cooldown to pass) before itself saving. If any other threads come along, they shouldn't do anything.

local YuanDB = false -- true if a thread is in the process of saving
local YuanWaiting = false -- true if a thread is waiting for a chance to save
Yuan.Changed:Connect(function()
    if YuanWaiting then return end -- this function is being run and another thread is waiting to run
    YuanWaiting = true
    while YuanDB do wait(1) end
    YuanWaiting = false
    YuanDB = true
    local success, msg = pcall(function()
        datast1:SetAsync(plr.UserId, Yuan.Value)
    end)
    if success then
        print('Data has been saved')
    else
        print('Data failed to save. Error message:", msg)
    end
    wait(10)
    YuanDB = false
end)

Note the pcall I added. SetAsync can error even if you give it proper data. If it were to error here, YuanDB would be stuck as true, preventing this value from ever saving again (for this player while on this server). Using pcall avoids that possibility.

Ad

Answer this question