I found a bug (to let those wanting to use this service immediately know, since I can’t make a public bug report - though I’ve just sent a message to the Bug Support group so hopefully they’ll publish the report later…)
If two UpdateAsync requests run at the same time when the initial value of the key is nil, neither request will be executed a second time.
Sample code:
mss = game:GetService("MemoryStoreService")
test = mss:GetSortedMap("Test")
s = os.clock()
timeout = 3
task.spawn(function()
print("spawn update", test:UpdateAsync("0", function(v) print("spawn received", v) return (v or 0) + 2 end, timeout))
print("spawn", os.clock() - s)
end)
print("main update", test:UpdateAsync("0", function(v) print("main received", v) return (v or 0) + 1 end, timeout))
print("main", os.clock() - s)
Sample output when it goes wrong:
spawn received nil
main received nil
spawn update 2
spawn 0.1831044999999
main update 1
main 0.1833445999946
(The rest of the time, one transform function will finish executing before the other one starts.)
Once the value exists, it seems to work as expected.
Just tested it: you can refresh the expiry with UpdateAsync (you can just return whatever the current value is in the transform function) or SetAsync (assuming you already know the value).
DataStores and MemoryStore will stay separate data spaces. OrderedDataStores will not become obsolete as a result of MemoryStore but it may help you create periodic leaderboards more easily. Some experiences may choose to base their leaderboards in MemoryStoreService alone which is fine!
Just do be mindful of the per-experience quota and that you leave enough room for other use cases of MemoryStore if you base your leaderboards in MemoryStoreService. The quotas are very generous but if you abuse them too badly you might find yourself running out.
Always remember to remove data you no longer need, very important point to using this service.
This is actually really cool. A few months ago, I made a server list system similar to how dedicated server browsers work. Instead of using my frankestein data store + messaging service spaghetti code, I can finally use one store to save both volatile and static data and have much shorter server matchmaking startup times.
Wow! I’m really excited about this. Perfect timing as we were just figured out that we can’t use MessagingService for our use case and was thinking about using an external service. Much prefer to use something native to Roblox.
I’ve read the allOrNothing parameter description like 10 times and still don’t quite understand what it does. Can someone help me understand what this is?
Reading into the new MemoryStoreService, I found it difficult to figure out how it fits into my workflow without any explicit use cases. There’s way too much written about the specification, but not enough about why we’d want to use it. I would like to see the wiki page(s) updated with some code samples.
Also, how does this compare to that other messaging service we were introduced to some time ago, if both can be used for ‘low-latency, high-throughput’ data manipulation?
The main advantage of MemoryStore over MessagingService is the disconnect from the data living on game servers. Servers do not need to establish some way of determining and managing which server is the source of truth.
For example in a queue, MessagingService must first determine which server is going to hold the queue, and then all servers have to successfully ask which server already has the queue, and when closing that server has to successfully hand off the queue before it closes.
With the MemoryStore the queue is a seperate entitity from game servers. There will always only be one, there is no need for servers to establish who is keeping track of it or hand it off.
OrderedDataStore is persistent, MemoryStore is not. So no, the use cases are different. You wouldn’t store a ranking you intend to persist on MemoryStore since you would not be able to store all player values on it at once for 30+ days.
I should have been more clear in the post. I would of course sync the memory store data with the players datastore values and then i would assign the priority queue based off of that. Of course, like the post mentioned, I would use datastores as a single source of truth. Hopefully this makes my post more clear
If the ReadAsync finds fewer items than the count parameter and allOrNothing is set to true it will return all the items available. If allOrNothing is true it will return nothing.
For example, let’s say I have a queue with 99 items, and I call :ReadAsync with a count of 100, by default it will return all of the items that it could fine (The 99 items). But if allOrNothing is set to true it will return nothing.
That’s a valid comparison, but the official documentation fails to make any mention of that. When we want to access a tutorial, we’d rather know in what applications this is useful in than how much memory we’re allowed to store on it at a time. I’ve been developing for well over 7 years, so you could only imagine how someone with one or two years will approach this. The first paragraph mentions general use-cases, but is nowhere as in-depth as with the DataStoreService page.