Coroutine's status is suspended when a function that it calls uses a method that yields

I want to make an easy to use data storage module

It needs to use coroutines to avoid jamming, but when i use GetAsync inside of a function in the coroutine it’s status changes to suspended

I have tried a repeat loop to wait until it suspends, but that gets bypassed entirely by this bug I have included the relevant code

getOrderedData function

local function getOrderedData(dataStore: OrderedDataStore): (boolean, DataStorePages | errorType)
	
	local attempts: number = 0
	local success: boolean = false
	local response: any = nil
	local overallResponse: {[string]: number} = {}
	
	repeat
		
		success, response = pcall(dataStore.GetSortedAsync, dataStore, false, 1) --right when this line runs the coroutine suspends
		
		if not success then
			overallResponse[response] = overallResponse[response] + 1 or 1
			attempts += 1
			task.wait(10)
		else
			overallResponse = response
		end
		
	until attempts >= 5 or success
	
	return success, overallResponse
end

getDataFromDataStore function

function module.schema.getDataFromDataStore(self: dataStore, key: string, default: data?): (boolean, data? | errorType)
	
	if self.gettingStores[key] then return false, "this datastore is already being accessed, please try again later. if this is incorrect, please make a report to the developers" end
	
	local coro = coroutine.create(function()
		
		self.gettingStores[key] = true
		
		local orderedDataStore: OrderedDataStore = DSS:GetOrderedDataStore(key.."/"..self.name)
		local globalDataStore: GlobalDataStore = DSS:GetDataStore(key.."/"..self.name)
		
		local attempts: number = 0
		local data: string = nil
		local success: boolean = false
		local response: data | errorType = nil
		local backup: boolean = false
		local versionGotten: number = 0
		local errorLog: {[string]: number} = {}
		
		local orderedSuccess: boolean, response: DataStorePages | errorType = getOrderedData(orderedDataStore) --this is when the coroutine gets suspended
--i have trimmed out irrelevant code, i only have it up to where the problem is caused.
end

edit: yes i know this is similar to one of my previous posts, but that one got no help and some of the info in it turned out to be wrong.

1 Like

Use coroutine.wrap instead of coroutine.create
When using coroutine.wrap , the coroutine will automatically resume after the GetAsync call (or any other yielding call) completes.

have you tried using response.key and response.value?

i have done coroutine.wrap. the problem is that it temporarily suspends for the yielding call and then resumes shortly after, so it messes up the order of the code.

what would those do? the response variable would either be an error code or a datastorepages object

Yeah my bad, not very helpful advice, considered running after using coroutine.create coroutine.resume perhaps? Keep in mind task.spawn returns a thread that you can pause and yield as well.