LuckPerms

LuckPerms

41.4k Downloads

Data Improvements

popcorn9499 opened this issue ยท 17 comments

commented

It would look alot nicer and possibly be nicer for syncing if you setup the database so you had a table purely for permissions and had a group id that it referenced. More like how say zperms and pex handle it. this would make it faster and easier to manage say editing the database if needed and help with synchronizing across the servers too. It might be a good idea if you set a config option for this to convert between the 2 or something.

Thanks for reading. Other than that this plugin looks like it could be really good. I would be willing to give ideas on how to do this.

commented

I agree.

I pretty much neglected the entire relational database concept with LuckPerms. (it's probably my biggest regret when making the plugin)

However, I can justify it in two ways:

  • The somewhat "intelligent" way of storing data about players means that even large servers don't have that much data stored. Only non-unique players get persisted.
  • It is very difficult write nice APIs and commands when the data is backed by multiple DB records.

Consider this:

  • A player has a set of permissions
  • These permissions dynamically change whilst a user is loaded in memory
  • In order to "save" a user, I would need to keep track of the changes made to that set alongside the user. Effectively, you'd have a set of live permissions, a set of permissions to be added on next save, and a set to be removed on next save. Whilst this isn't impossible, it's not very tidy (or clever imho.)

If you can think of a simple way to solve no. 3 above, then I'll happily make the change for all SQL backed datastores.

commented

I know zperms seemed to have a good method on this as ive used it and not had problems with it syncing stuff and overriding stuff. Here is the github. honestly tho i dont rlly know java so im not too sure what im reading exactly but it looked as if this would be something of interest.

I'm thinking that the simplest way to do this would be run through the permissions in memory and remove what is in the to be removed table. Then after that add back in what you want to add. Periodically then you can reorganize the table. Thats how id describe what i think is the best method. Maybe have it as a option and if people dont want to use that method let them disable it?

thanks for reading. Sorry that i might not of been much help. However i do understand what your talking about

commented

Yeah - I've used/read/modified zPermissions a lot before, quite familiar with how they do it.

Perhaps it's something to work towards. No promises on when it will happen, but hopefully at some point in the future. :)

commented

Thanks for looking into this. If i ever get good with java i'll try and look again with more knowledge and help you with this.

commented

You'd have to literally execute the commands within the same couple of seconds for there to any any overrides, and no, this wouldn't fix #85. That's something completely different.

commented

In order to "save" a user, I would need to keep track of the changes made to that set alongside the user. Effectively, you'd have a set of live permissions, a set of permissions to be added on next save, and a set to be removed on next save. Whilst this isn't impossible, it's not very tidy (or clever imho.)

This would resolve: #85

What about permissions being modified from two servers during the same three minutes (default refresh interval). Wouldn't they overwrite each other, or does it load the latest from database and merge before saving?

I doubt it could be fully collision safe unless there is a master in place. But doing it like this should cause less issues than it does atm:

  1. do local adjustment (in memory)
  2. direct async call or add to queue -> write adjustment to database and push it to all clients (redis)

Of course this requires a normalized database structure. But whether it is stored in a one level json object or a table shouldn't make a big difference, after all that is what joins are for.

commented

First off Slind14 if you do this properly it will modify the database at the same time as the edit was done. This makes it unlikely that the same permission will be edited twice. which should cause less problems of syncing problems. Because to my understanding the refresh everything every 3 minutes is just for reading the database, not for writing to it. correct?
And no it cant be fully collision safe but even the method rn isnt either im betting.

commented

I was talking about the current way it works.

commented

oh ok. I wasn't sure sorry.

commented

When Server B sets the new prefix, it will pull the latest data from MySQL.

You would literally have to do it within the same few seconds.

commented

ahh ok, so it does merge the data first?

commented

question. how are you planning to handle telling the other servers that there was a change? is it gonna be like zpermissions where it has a version count and if the version is newer it goes and forces a refresh of the permissions?

commented

@Slind14 Yes.

@popcorn9499 Not atm. Currently there's just a refresh interval and/or Redis PubSub.

commented

Wouldn't that be a good thing to have tho? Just asking if it would possibly make less updates happen when they arent needed. would it not?

commented

Yeah - can be added to this issue.

commented

Consider this:
0:00 Server A/B refresh perms
0:15 Server A sets permission.awesome to true
2:45 Server B sets a new prefix
3:00 Server A/B refresh perms
=> permission.awesome: true is lost

Its a wide window

commented

This was completed in 960c229. I'm happy with the outcome of this ticket, but if you have any further suggestions let me know.

It's certainly a lot better than it was before. :)