Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetAsync problems alongside Persistence #80

Open
blinkybool opened this issue Jul 27, 2022 · 2 comments
Open

GetAsync problems alongside Persistence #80

blinkybool opened this issue Jul 27, 2022 · 2 comments
Labels
bug Something isn't working

Comments

@blinkybool
Copy link
Member

I entered Symbolic Wilds 1 and noticed that after all of the boards were loaded, there was a GetAsync queue warning. I think this is because Persistence uses the budget down to 0 (but never below that), and then some other module (metaadmin, metaportal, Avatar?) does a getAsync while there's still zero budget.

All GetAsync's in Persistence are guarded by a check to make sure the budget is non-zero.

local function get(dataStore: DataStore, key: string)
	while DataStoreService:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.GetAsync) <= 0 do
		-- TODO maybe make this longer?
		task.wait()
	end

	--[[
		No pcall because we catch the error in `restoreAll`
		Note we are not storing the 2nd, 3rd, 4th return values of getAsync
	--]]
	-- print("getting key", key)
	local result = dataStore:GetAsync(key)

	return result
end

So I see two options here

  1. I set a lower limit for the GetAsync get async budget in persistence (so it says while budget <= LOWER_LIMIT instead)
  2. Every other use of GetAsync should be responsible for not requesting when there's no budget (likewise for other DataStore calls)

I guess doing (2) doesn't mean not doing (1). Perhaps every module can make use of some small lower limit like 5, just in case some additional rogue code is too greedy. If we were to just do (1), then I'd have to set the lower limit much higher because I'm babysitting demanding children that will query the datastore whenever the heck they want.

I'm curious how other developers handle datastore budgets. The way it's documented, it seems like the suggestion is "don't make requests too often, and you'll be fine", so then you go and try to tune the frequency of your datastore requests according to the rate that they refill the budget, with some generous margins to avoid tempting fate. This is how old persistence worked.

But it seems inevitable to me that when you combine multiple independent systems that are all doing this, the timing logic fails and you accidentally send too many requests. Even on its own, if your timing logic is too careful, you retrieve data much slower than you could, and if you try to time things as close as possible to the limit without exceeding it, you'll probably exceed it by accident from time to time.

I haven't seen the technique I implemented suggested anywhere, is there some reason we shouldn't just do it in all metauni code?

@blinkybool blinkybool added the bug Something isn't working label Jul 27, 2022
@blinkybool
Copy link
Member Author

From metauni-dev meeting: We should do this budget check for every async call in all code, and just set some small "in case" lower limit, like 5 or 10.

@blinkybool
Copy link
Member Author

We need to Ctrl+F for SetAsyncs and GetAsyncs in the rest of our code, and make sure it all yields for the budget

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant