Roblox icon indicating copy to clipboard operation
Roblox copied to clipboard

SaveAsync clones tables before giving them to BeforeSave

Open Masken8 opened this issue 4 years ago • 2 comments

The data I'm putting in the cache is a table of metatable based objects and those objects reference objects that reference them.

Cause: Save clones the table and then gives it to BeforeSave. Stack Trace:

Script 'ReplicatedStorage.rbxts_include.node_modules.datastore2.src.TableUtil', Line 8 - function clone (x4996)  -  Studio  -  TableUtil:8
Script 'ReplicatedStorage.rbxts_include.node_modules.datastore2.src', Line 46 - function clone  -  Studio  -  src:46
Script 'ReplicatedStorage.rbxts_include.node_modules.datastore2.src', Line 305  -  Studio  -  src:305
Script 'ReplicatedStorage.rbxts_include.node_modules.datastore2.src.Promise', Line 218

BeforeSave: Yes BeforeInitialGet: Yes The tables output by my BeforeSave and BeforeInitialGet do not include any circular references. Saving Method: Standard

Do note that I am using https://github.com/osyrisrblx/rbx-datastore2 but it's using the same underlying code. The script that handles this seems to be up to date.

Masken8 avatar Dec 30 '20 20:12 Masken8

Can you provide an MVCE?

Kampfkarren avatar Dec 30 '20 21:12 Kampfkarren

Edit: Place file https://www.roblox.com/games/6167461405/DS2MVCE

This should do it

local Players = game:GetService("Players")
local DataStore2 = require(PathToDataStore2)

local MyClass = {}
MyClass.__index = MyClass

function MyClass.new(obj2, stuff)
    local self = {
        object2Ref = obj2,
        stuff = stuff
    }

    setmetatable(self, MyClass)

    return self
end

local MyClass2 = {}
MyClass2.__index = MyClass2

function MyClass2.new()
    local self = {
        object1Ref = nil,
    }

    setmetatable(self, MyClass2)

    return self
end

function Serialize(deserialized)
    local serializedTable = {}
    for _, v in pairs(deserialized) do
        table.insert(serializedTable, {
            stuff = v.stuff,
        })
    end
    return serializedTable
end

DataStore2.PatchGlobalSettings({
	SavingMethod = "Standard",
});

DataStore2.Combine("Data", "CircularReferenceTable");

Players.PlayerAdded:Connect(function(player)
    local CircularReferenceTableStore = DataStore2("CircularReferenceTable", player)
    local Object2 = MyClass2.new()
    local Object = MyClass.new(Object2, "asdf")
    Object2.object1Ref = Object

    CircularReferenceTableStore:BeforeSave(Serialize)

    CircularReferenceTableStore:Set({ Object })
    CircularReferenceTableStore:Save()
end)

Masken8 avatar Dec 30 '20 21:12 Masken8