QuickNetwork - A powerful hybrid alternative to ProfileService and DataStore2

I don’t understand the point of this module. This module will become obsolete very soon, with the addition of built-in backups. Also, how do I know if all of your methods work? Has this been used in major games? How often does data loss occur? I don’t think this is any better than DataStore2 or ProfileService. I’ll just stick to ProfileService.

This module has been battle tested thoroughly and knowing if the methods work is a stupid question, test it out your self; obviously they do work.

DataStore2 is now inferior, it just only has a redundant way of saving backups which won’t help in data loss that effectively, you are guaranteed to load with old data instead of the latest because it doesn’t provide session locking and doesn’t handle any edge cases. Not to mention the bloated API and no flexibility.

Profile service is a decent module, with features like session locking but doesn’t provide you any ways to do the following / disadvantages:

  • Know when data is successfully saved or wiped / reset.

  • Handle data corruption / error with flexibility - you can only tell if data has corrupted but cannot decide whether to load backup data or a custom data, or just simply let the module handle it.

  • Far less flexible: you cannot control if you want ProfileService to save data on server shutdown or enable auto saving etc.

  • Doesn’t take extra steps to save / load data with precaution.

This module is a hybrid combination of both with 4x more flexibility and control, easy to use and light weight. Since this module is battle tested, there is no need to worry about data loss, as it saves data a better than both DataStore2 and ProfileService, effectively handles data loss and also minimises API calls than both.

You can also create your own methods on top of existing ones as well.

PS:

This module also provides an easy way to combine data from different data stores or keys all into one, something which is very necessary but something which DataStore2 or ProfileService don’t
provide.

Saying this module will “become obsolete” is highly an subjective and immature statement without any proof or logic behind.

2 Likes

I was talking about Roblox’s plan to provide built-in backups for datastores. It will make this obsolete. And replying with such a rude attitude is immature :wink: .

Of course I know how to test it myself, it appears you did not understand my question. Allow me to explain it like I would to a two year old. How do I know whether it works on a large scale or not? It may work a couple of times while testing, but without large-scale testing, it is impossible to know whether this is a good module or not.

PS.

You answered none of the questions I asked and instead replied in a very rude way. This is a step back if you want success in your module. Maybe instead of ranting on how “stupid” my questions were, you could actually answer them next time. :slightly_smiling_face:

2 Likes

Btw, when I tested your module, if data wasn’t changed, the data wouldn’t release. That should not be a feature with session locking at all.

1 Like

This is really nice, I’ll definitely use this. A lot easier to use than profile service.

Very nice module, thank you for your contribution to the open-source community. :heart:

Epic! I am using it in my game. Very reliable.

This man probably spent months designing this datastore system, which looks great. If you have nothing productive to say, don’t complain. If you have critiques, say them in a positive way. Just because you feel he made a mistake does not mean you should attack him over it. This is a problem in many community resource reply sections.

2 Likes

[26/4/2021]: QuickNetwork Update [v1.60]

  • Important session lock bug fix where data would be saved even if it wasn’t the latest, though it can still be saved if force saved.

  • Fixed a bug where GetDataNetwork would initalize MockDataStoreService before data store errors were handled.

  • Fixed a bug where MockDataStoreService wouldn’t be initialized properly, causing bugs loading data.

  • GetDataNetwork now yields unless data store errors have been handled. The yield will take as long as a single GetAsync call will take.

  • Data whose session lock was stealed will now not save the data unnecessarily upon loading it via an UpdateAsync call.

Update your module here:

3 Likes

Is it possible to remove specific keys with this module?

What do you mean by remove specific keys?

A method similar to Roblox’s RemoveAsync.

Yes, use Data:Wipe to wipe the data.

So, for example, if I wanted to remove the key “PetName” because pets were removed from the game. I suppose I would have to copy the data first, wipe data, then Data:Set everything but PetName from the copied table.

Could you also provide an example on how Data:SetTable works please.

Don’t use wipe for that, instead remove the data that corresponds to the key PetName inside the data.

Data:SetTable(key, value, table) works by setting the key in the table provided as the last argument to value.

It seems your Data:SetTable method isn’t flexible with trying to index multiple nested tables. So this what I suggest instead:

Your Method →

function Data:SetTable(tabl, key, value)
	assert(typeof(tabl) == "table", INVALID_ARGUMENT_TYPE:format(1, "table", typeof(tabl)))
	
	if self[tabl][key] == value then
		return
	end

	self[tabl][key] = value
	self.MetaData.Updated = true
	self.ListenToUpdate:Fire(key, value, tabl)
end

Iterative Method →

function Data:SetTable(Value, ...)	
	local Arguments = {...}
	local Len = #Arguments
	
	local Temp = self
	for Index, Tabl in ipairs(Arguments) do
		if Index == Len then break end
		Temp = Temp[tabl]
	end
	Temp[Arguments[Len]] = Value
end

Note* The last argument in ... is the index you want to change the value to.

1 Like

I was going to update it to support nested table support anyways in the next update since I was lazy, thanks!

1 Like

Kind of weird having these need a :Connect, you could probably add a __call metamethod to the Signal API you’re using which would handle that, I guess something like this, I kind of wanna do that too.

Signal.__call = function(self, _, ...)
    return self:Connect(...); --???
end)

because then you can use:

data:ListenToUpdate(function()
    print('woah.')
end)

--\\ Instead of the weird:

data.ListenToUpdate:Connect(function()
    print('bleh.')
end)

If I was gonna stay with :Connect, I would have at least called it onUpdate or something. ListenToUpdate is more so a name for a connector function.

1 Like

Please try to make valid points regarding something that should be considered in the first place. The way you want those signals to work is weird, not mine. ListenToUpdate:Connect(func) makes a bit more sense than ListenToUpdate(func).

1 Like

When you can’t take constructive criticism. Literally no one else does it that way, just re-think about that.

I know it’s an event. I’m talking about the wording here and the way you connect a function, is just non-standard given the name you gave it. I’m not answering anything else about it.

3 Likes