Memory Store Service Tutorial

Hello there, wonder if there’s a more efficient way of detecting new queue data than using while true do loops.

sadly, nope. As of this post, there are no built in events to detect when a new item is added to a queue. The best way is while loops. You could use RunService, but you could easily be ratelimited if you do that.

2 Likes

Anyways thanks for this post, learnt something new!

2 Likes

Yoooo, I couldn’t learn memorystoreservice until you came with clear explanation. Tysm

3 Likes

np. Glad I coud help! It makes my day when someone tells me what I made help them :slight_smile:

1 Like

not sure if people are interested in this, but should I add a tutorial on how to use Sorted Maps?

  • Yes
  • No

0 voters

Alright, seems that people want a Sorted Maps tutorial. I’ll start on that now :slight_smile:

alr just finished the sorted maps part.

If I missed something make sure to point it out(didn’t have that much time to write it.)

4 Likes

This is very useful for making servers.
Thanks for this tutorial!
I really needed a better understanding of how it works. :smile:

1 Like

Hey @TheH0meLands, question about the above tutorials:

If I am understanding this correctly it seems each server would have code for “removing” new items from the Queue or Map (you use MemoryStoreQueue:ReadAsync which makes them invisible to other ReadAsync calls for the period of the invisibility timeout and MemoryStoreSortedMap:RemoveAsync which removes the data from the map)

If the Queue or Map is shared across all servers, then if one server removes new data how would other servers get this data as well if it is removed? Say for example a player joins, one server reads this and removes it, wouldn’t all other servers not find this join message after it has been removed? How can the data be shared across all servers if each server can remove items?

1 Like

oh its a roblox admin? Whyd u delete ur posts lol?

if I understand your question correctly, if you want to update the queue, you have to re-read it.

Sorry I’m not sure what you mean… let me try to explain with an example of how I’m thinking about this:

Screen Shot 2022-09-24 at 10.32.35 PM

Suppose there is a priority queue that exists between 3 servers (red, green and blue). It has the values A, B and C in it with A being at the top of the queue. Red server then calls ReadAsync.

The red server reads in value A and based on the docs it says “MemoryStoreQueue:ReadAsync makes them invisible to other ReadAsync calls”. So now A is shaded gray to mark it as invisible. Now green server calls ReadAsync on the queue.

The green server reads in value B (since A is invisible) and then makes B invisible to future ReadAsync calls. I must be misunderstanding something because I don’t see how the Memory Store works across multiple servers if they don’t all read / get updated with the same data.

For context I’m trying to use MemoryStore to store a list of Servers and the Players in them across all Servers.

honestly I dont really understand your question but if you want to keep stuff up to sync just do a while true do loop and re-read it every second or 2.

Guess I’ll try one more time, my question boils down to this:

The queue or map is shared between servers, but each server can individually remove data from them (i.e. if one server removes some data, another server will not read it as it has been removed). How can every server ensure they read all data if each server is removing data asyncronously?

It sounds like even if one server removes data from the queue or map, other servers can still read it, but this is confusing to me and isn’t explained in the documentation.

A MemoryStoreQueue should be used to store a list of tasks, so when one server reads a task other servers won’t try to also do the task.

However when creating your MemoryStoreQueue you can set an invisibility timeout, so you could set it to 0 to not have any invisibility.


For a server list with players a MemoryStoreSortedMap is more fitting.

i haven’t tried using this information in my own code but i think this is gonna solve a problem i’ve been having fore a while. thank u for this tutorial

1 Like

Actually, there is one way you could detect if a new item has been added to a queue. Messaging service could publish a message to all the servers, and then have the other servers listen for that message.

For example (Pseudocode):

On item added to queue do
    PublishMessage("ItemAddedToQueue")
end

OnItemAddedToQueueMessageRecieved do
    ProcessNewItemInQueue()
end

Would I recommend this solution? Only if you absolutely need it. Messaging service does have limitations, so you may be better off using a while loop.

More info on messaging service: MessagingService | Documentation - Roblox Creator Hub

1 Like

Your tutorial for SortedMap:GetRangeAsync() is missing one bit of information. GetRangeAsync accepts up to 3 parameters, with the third one being the key you want to start the search from. This means you can actually get ALL the data (over 200) by calling GetRangeAsync and specifying the third parameter.

Below is code from my Memory Store - Sorted Map Service free models:

-- Gets range or all keys and data from sorted map data
local function GetSortedMapRange(sortedMapName: string, count: number?, exclusiveLowerBoundKey: string?)
	local sortedMap: MemoryStoreSortedMap = GetSortedMap(sortedMapName)

	-- if count is nil, then get all sorted map data
	local getAll = false
	if count == nil then
		count = 200
		getAll = true
	end


	-- Get data
	local function GetRangeAsync(sortedMap, count, exclusiveLowerBoundKey)
		return sortedMap:GetRangeAsync(Enum.SortDirection.Ascending, count, exclusiveLowerBoundKey)
	end

	local success, data = RepeatCallFunction(GetRangeAsync, sortedMap, count, exclusiveLowerBoundKey)

	-- If fail, return fail and error message
	if not success then return false, data end

	-- If data is less than 200 or reached count, then means reached end of list
	if #data < 200 or (count - #data == 0 and getAll == false) then
		return true, data
	end

	-- Reduce count OR set to nil if getting all data
	count -= #data
	if getAll then
		count = nil
	end

	-- Call itself with exclusive lower bound key (so continues sorted map list)
	local recursiveSuccess, recursiveData = GetSortedMapRange(sortedMapName, nil, data[#data].Key)
	-- If fail, return fail and error message
	if not recursiveSuccess then return false, recursiveData end

	task.desynchronize()
	-- Loop through recursive data and add to existing data
	for _, recursiveData in pairs(recursiveData) do
		table.insert(data, recursiveData)
	end
	task.synchronize()

	return true, data
end

The above uses a recursive loop to call itself and get the next 200 data, and continues until it gets all the data.

If anyone else here is interested in using a memory store script with repeat call attempts and temporary cache, then feel free to check my script here: Memory Store - Sorted Map Service (by AstrophsicaDev)

MessagingService would be a great solution