New secure datastore module

The module I wrote and was using to save my data was pretty old and most of the code wasn’t that good, so I decided to rewrite it and add more security.

Can I get any feedback?

Also, when saving data, I’ve chosen to save to one main one and one backup one, though. Would this cause any problems?

--Rek's custom datastore module

local dataFunctions = {}

local dss = game:GetService("DataStoreService")
local backup = dss:GetDataStore("BackupData")

local sessionData = {}

game.Players.PlayerAdded:Connect(function(player)
	if not sessionData[tostring(player.UserId)] then
		sessionData[tostring(player.UserId)] = {}
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	if sessionData[tostring(player.UserId)] then
		sessionData[tostring(player.UserId)] = nil
	end
end)

function dataFunctions:InitializeData(player, datastore, datatable, dataIndex) -- setting something to the retrieved data
	local store = dss:GetDataStore(datastore)
	local key = "Player_"..player.UserId
	
	local data 
	
	local success = pcall(function()
		data = store:GetAsync(key)
	end)
	
	if success then 
		if data then 
			sessionData[tostring(player.UserId)] = data
			local newIndex = data[dataIndex]
			
			if newIndex then
				for index, value in pairs(newIndex) do
					datatable[index] = value
				end 
			end	
		end
	else
		print("Failed to initialize data. Retrying...")
		
		local tries = 0
		local retrySuccess
		
		repeat 
			tries += 1
			
			retrySuccess = pcall(function()
				data = store:GetAsync(key)
			end)
			
			if not retrySuccess then
				wait(1)
			end
			
		until tries > 3 or retrySuccess
		
		if retrySuccess then
			if data then
				sessionData[tostring(player.UserId)] = data
				local newIndex = data[dataIndex]
			
				if newIndex then
					
					for index, value in pairs(newIndex) do
						datatable[index] = value
					end 
				end	
			end
		else
			local data
			
			local success = pcall(function()
				data = backup:GetAsync(key)
			end)
			
			if success then
				if data then
					sessionData[tostring(player.UserId)] = data
					local newIndex = data[dataIndex]
					
					if newIndex then
						for index, value in pairs(newIndex) do
							datatable[index] = value
						end
					end	
				end
			end
			
			if not success or not data then
				
				print("Retries failed. Now retrieving any backup data.")
				
				local tries = 0
				local gotBackup
				
				repeat
					tries += 1
					
					gotBackup = pcall(function()
						data = backup:GetAsync(key)
					end)
					
					if not gotBackup then
						wait(1)
					end
				until tries > 3 or gotBackup
				
				
				if gotBackup then
					if data then
						local newIndex = data[dataIndex]
						sessionData[tostring(player.UserId)] = data
						
						if newIndex then
							for index, value in pairs(newIndex) do
								datatable[index] = value
							end
						end	
					end
				else 
					print("Failed to load data for " .. player.Name .. ".")
				end
			end	
		end
	end
end

function dataFunctions:SaveData(player, datastore, datatable, dataIndex) -- saving 
	local key = "Player_"..player.UserId
	local store = dss:GetDataStore(datastore)
	
	local data = datatable or sessionData[tostring(player.UserId)]
	
	local function update(old)
		if dataIndex then
			if old then 
				old[dataIndex] = datatable
			else
				old = {}
				old[dataIndex] = datatable
			end
			
			return old
		else
			return datatable
		end
	end
	
	local function backupUpdate(old)
		if dataIndex then
			if old then 
				old[dataIndex] = sessionData[tostring(player.UserId)]
			else
				old = {}
				old[dataIndex] = sessionData[tostring(player.UserId)]
			end
			
			return old
		else
			return sessionData[tostring(player.UserId)]
		end
	end
	
	local function save(func)
		store:UpdateAsync(key, func)
		backup:UpdateAsync(key, func)
	end

	local success = pcall(save(update))
	
	if success then
		print("Successfully saved data for ".. player.Name..".")
	end
	
	if not success then 
		print("Data save failed. Retrying...")
		
		local retry 
		local tries = 0
		
		repeat 
			tries += 1
			
			retry = pcall(save(update))
			
			if not retry then 
				wait(1)
			end
			
		until tries > 3 or retry 
		
		if retry then 
			print("Saved data for "..player.Name)
		else
			print("Data save retry failed. Attempting to save data from last known session...")	
			
			local savedBackup = pcall(save(backupUpdate))
			
			if not savedBackup then 
				local tries = 0
				local successBackup
				
				repeat
					tries += 1
					
					successBackup = pcall(save(backupUpdate))
					
					if not successBackup then 
						wait(1)
					end
					
				until tries > 3 or successBackup
				
				if successBackup then 
					print("Saved the last known session data for "..player.Name..".")
				end
			end		
		end
	end
	
end

function dataFunctions:UpdateSession(player, datatable, index) -- session caching
	
	local key = "Player_"..player.UserId
	
	if index then 
		sessionData[tostring(player.UserId)][index] = datatable
	else
		sessionData[tostring(player.UserId)] = datatable
	end
	
	local timestamp = os.date("*t", os.time())
	
	print("Updated session at "..timestamp["hour"]..":"..timestamp["min"]..":"..timestamp["sec"])
	
end

return dataFunctions

If there’s any problems, please correct me.