DataStores, if SetAsync or UpdateAsync gets called, but is not finished with writing yet, what will GetAsync do?

I’ve been trying to do tests to figure this out. But I couldn’t figure this clearly out.

I’ve been spamming :SetAsync() and :GetAsync() and even use :UpdateAsync(), and then something with the MemoryStoreQueue, to tell if something is writing or not… (but the results where mehh…)

 

So I am going to ask this here.

Let’s say hypothetically, you’re using :UpdateAsync() BUT AT THE SAME TIME, you join a SubPlace e.g. through TeleportService.

Let’s say, :UpdateAsync("key") has been called but IS NOT finished yet.

But you loaded into the SubPlace and are using :GetAsync("key") on the same key…

The question here is, whether it’s going to load the OLD or the NEW one.

Because I don’t think there’s anything that guarantees that, is there? That’s what I’ve been trying to test.
 

However, there’s also :ListVersionsAsync, so the question is… if something like :SetAsync or :UpdateAsync gets called, BUT IS NOT FINISHED by internal functions…

Does it reserve a new version though, and yield any future :GetAsync() to get the newest data, even if it wasn’t written yet?

It will return the old data before UpdateAsync was called. This is why it is crucial to have session locking. Such as by using ProfileService.

I’ve seen ProfileService somewhere, not sure if it was DOORS.

How does it session lock though?

It automatically ensures that a Profile can only be loaded on one server at a time. If a Profile is attempted to be loaded while it is already loaded it will first release the profile (which will save the state and lock it) before loading it on the new server.

I wonder if it does that with MemoryStoreQueue.

I sorta checked and tried understanding.

ProfileService uses ActiveSession and it uses that to check the session-locking relevant stuff.

ActiveSession = {place_id, game_job_id}

It puts that in a MetaData table

so MetaData.ActiveSession and that’s part of the Player Data

There’s also a ForceLoadSession but not sure what that is used for.

Summary
--[[
	Saved profile structure:
	
	DataStoreProfile = {
		Data = {},
		MetaData = {
			ProfileCreateTime = 0,
			SessionLoadCount = 0,
			ActiveSession = {place_id, game_job_id} / nil,
			ForceLoadSession = {place_id, game_job_id} / nil,
			MetaTags = {},
			LastUpdate = 0, -- os.time()
		},
		RobloxMetaData = {},
		UserIds = {},
		GlobalUpdates = {
			update_index,
			{
				{update_id, version_id, update_locked, update_data},
				...
			}
		},
	}
--]]

Not exactly sure how it uses ActiveSession, but it’s a start at understand on how it works.

1 Like

This is the default behavior I mentioned before but didn’t say it was called ForceLoad.

So if you force load a Profile. How does it save? Or does it just while loop until “ActiveSession” is gone?

I’ve made a documentation about it.

https://github.com/MadStudioRoblox/ProfileService/pull/39

A full analysis (hopefully)

 

This is also the final solution for this thread, now you can write your own session-locking mechanic, the problem here is the concept. You Load data once and store it… e.g… I already have a perfect concept on how ProfileService can be improved entirely, where instead of using a MetaData table. I’d use the keyInfo.

I don’t have to worry about ForceLoad, because I can keep track of .UpdatedTime :person_shrugging:

 
 

ProfileService’s DataStore structure is something like.

Keeping track whether a DataStore is being read or not directly in the DataStore area, be it KeyInfo or whatever, is a really smart approach, similar to how you can lock metatables.

{
   Data = {}
   MetaData = {}
}

ProfileService checks locally if the store is already loaded on the same server.

If it isn’t, it checks ActiveSession, which stores {PlaceId, JobId}.

By default it ForceLoads, meaning that it will try a defined amount of time, pushing in ForceLoadSession with the same data structure of ActiveSession. If ForceLoadSession survives and does not get overwritten (since everything is written in the returned data directly)

If that fails, it will abort.

 

However, there’s another check. It checks another custom Metadata LastUpdate, if the elapsed time is greater than the defined amount in the settings, it will immediately steal the session, because it will assume the other session is dead.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.