ServerDataStore Issue (advanced)

I am creating a global Int value that can be updated across servers into 1 cloud server. Here is the code to what I have done so far:

	local ServerDataStore = DataStoreService:GetDataStore("ServerDataStore")
	
	ServerDataStore:UpdateAsync("ServerDataKey", function(CurrentData) --Session Lock
		if CurrentData == nil then
			print("ServerData is nil!")
			return
		end
		if CurrentData.ServerInfo.SessionJobId == "" then
			print("Current Stored JobId: None!")
		elseif CurrentData.ServerInfo.SessionJobId ~= "" then
			print("Current Stored JobId: ".. tostring(CurrentData.ServerInfo.SessionJobId))
		end

		if CurrentData.ServerInfo.SessionJobId == "" then
			print("Set Job Id: ".. game.JobId)
			CurrentData.ServerInfo.SessionJobId = game.JobId
			return CurrentData
		else
			print("Session JobId Exist Already")
		end
	end)
	--This Part above checks to see if a server is already set as the cloud server, if it is not, it sets the current server as the cloud server.
	
	_G.AccumulatedBeli = 0
	_G.AccumulatedSink = 0
	-- The _G.AccumulatedBeli value is the total amount of money that was "created" from players completing quest and earning money. The _G.AccumulatedSink is the total amount of money destroyed when players bought items from npcs or upgraded their gear.
	local PublishDataDebounce = false
	
	print("Checking if Cloud Server")
	local ServerData = ServerDataStore:GetAsync("ServerDataKey")
	if game.JobId == ServerData.ServerInfo.SessionJobId then
		print("Inside Cloud Server")
		
		local function Subscribe(DataInfo) -- This function fires if the server is a cloud server.
			local ServerData = ServerDataStore:GetAsync("ServerDataKey")
			if game.JobId == ServerData.ServerInfo.SessionJobId then

				local AddToDataDebounce = false

				local NewDataInfo = HTTPSService:JSONDecode(DataInfo) --Decode the JSONTable

				_G.GlobalAccumulatedBeli += DataInfo["AccumulatedBeli"]
				_G.GlobalAccumulatedSink += DataInfo["AccumulatedSink"] -- These values here do the same thing the other values do but they just combine the accumulated amount across all the servers running.

				RunService.Stepped:Connect(function()
					if not AddToDataDebounce then
						AddToDataDebounce = true
						wait(10) -- How often it gets put into the DataStore
						ServerDataStore:UpdateAsync("ServerDataKey", function(OldData)
							OldData.ServerData.GlobalBeli = (OldData.ServerData.GlobalBeli + (_G.GlobalAccumulatedBeli + _G.AccumulatedBeli)) - (_G.GlobalAccumulatedSink + _G.AccumulatedSink);
							OldData.ServerData.GlobalBeliSink += _G.AccumulatedSink; --The stuff above adds the GlobalAccumulatedMoney and the servers own Accumulated money cause it didnt pass it through the messeging service

							_G.GlobalAccumulatedBeli = 0
							_G.GlobalAccumulatedSink = 0

							_G.AccumulatedBeli = 0
							_G.AccumulatedSink = 0 -- Resets the money

							print("Changed AccumulatedBeli to ".. AddComma(OldData.ServerData.GlobalBeli))
						end)

						AddToDataDebounce = false
					end
				end)

				local AddToDataDebounce = false

			end
		end

		MessagingService:SubscribeAsync("AccumulatedData", Subscribe)
	else
		print("Not Inside Cloud Server")
		print("The Cloud server JobId is ".. tostring(ServerData.ServerInfo.SessionJobId))
		RunService.Stepped:Connect(function()
			if not PublishDataDebounce then
				PublishDataDebounce = true
				wait(10)
				local DataInfo = {
					["AccumulatedBeli"] = tonumber(_G.AccumulatedBeli),
					["AccumulatedSink"] = tonumber(_G.AccumulatedSink)
				}
				local EncodedData = HTTPSService:JSONEncode(DataInfo) -- Encodes the JSONTable
				MessagingService:PublishAsync("AccumulatedData", EncodedData)
				print("Published")
				PublishDataDebounce = false
			end
		end)
	end
	
	game:BindToClose(function() -- Resets the sessionjobid in the datastore
		local ServerData = ServerDataStore:GetAsync("ServerDataKey")
		if game.JobId == ServerData.ServerInfo.SessionJobId then
			ServerDataStore:UpdateAsync("ServerDataKey", function(CurrentData)
				CurrentData.ServerInfo.SessionJobId = ""
				return CurrentData
			end)
		end
	end)

I run this but this happens:


So in the first game on the right that is the cloud server. it prints Set Job Id: (JobId) but for some reason it still publishes a message to the cloud server even though it is the cloud server. Can someone help?

Datastore operations aren’t instantaneous, so you are probably getting data too soon, indicated by the empty jobId.

You should use the data that you got from the UpdateAsync operation rather than reading it again immediately after.

As a side note, you should use Heartbeat instead of Stepped when your code is not physics related and doesn’t need to be run before the physics step.

3 Likes

Okay, I got it to work. The issue that I had was the GetAsync was not actually getting the value from the datastore. So I created a _G. Variable and set it to true if the server was a cloud server and went from there.

1 Like