Lookups being rate limited by Mojang #155


  • Defect
  • Accepted
Open
Assigned to _ForgeUser1494830
  • _ForgeUser9883694 created this issue Jul 16, 2014

    Mojang just implemented rate limiting today, it looks like, and group lookups occasionally give this error:

    http://i.imgur.com/Q7cQuE9.png

    This instance does have around 1 login every 3 seconds, so it would be useful if group lookups could be done locally in order to avoid rate limiting or broken package setting during session downtime.

    select name from entities where display_name='vemacs'; seems to work as a query.

  • _ForgeUser9883694 added the tags New Defect Jul 16, 2014
  • _ForgeUser9883694 edited description Jul 16, 2014
  • _ForgeUser8721736 posted a comment Jul 16, 2014

    Beat me to it Vemacs XD

  • _ForgeUser9883694 edited description Jul 16, 2014
  • _ForgeUser1494830 posted a comment Jul 16, 2014

    But then UUIDs would no longer be authoritative.

    zPerms is at the point where all queries and lookups are keyed solely by UUID. Using the local database for name -> UUID mapping seems like a step backwards.

    The remote lookup to Mojang's server is only done as a last resort. So that means you are executing a command on an offline player who has been offline for some time. In your use case, has the player ever logged into the server?

    If you are using 1.3beta1, admittedly the UUID cache settings were very short. Tweaking the settings (uuid-cache-size & uuid-cache-ttl, both hidden options) might be a viable workaround. The recent dev builds increased the defaults of these options to 1000 entries and 120 minutes.

    Until Mojang actually enables name changes, uuid-cache-ttl can be increased to even larger values (a week, a month). Mojang's own UUID cache (usercache.json) seems to use 30-day timeouts.

    Also somewhat related is #149, brought about by this thread.

    It seems like it will be a good idea to catch HTTP 429 and retry after some delay. I'll look into that. No doubt this also affects migration.

  • _ForgeUser1494830 removed a tag New Jul 16, 2014
  • _ForgeUser1494830 added a tag Accepted Jul 16, 2014
  • _ForgeUser8721736 posted a comment Jul 16, 2014

    Just wanted to let you know that your efforts are appreciated :)

  • _ForgeUser1494830 posted a comment Jul 16, 2014

    I don't think the retry-on-HTTP-429 thing will work. It seems once you're locked out, you're locked out for a good amount of time. (And I'm guessing Mojang doesn't publicize their rate limiting parameters.)

    The only reason I'm not willing to use the database for name -> UUID mapping is because those mappings don't expire. Additionally, not everyone in the system is in the entities table.

    (I could add a display name expiry column and perform the query on both entities and memberships tables, but then that's really mucking up the design. A separate UUID cache is cleaner.)

    I think caching is the way to solve this. As long as your UUID cache expiry is long enough and the player has visited your server "recently," then zPerms won't have to query Mojang.

    (If they've never visited your server, then there's actually nothing I can do regardless. The UUID has to come from somewhere and it won't be in the database.)

    So for now, I recommend increasing the UUID cache settings:

    uuid-cache-size: 1000
    uuid-cache-ttl: 10080
    

    (These are hidden options so they must be added to config.yml)

    uuid-cache-ttl is in minutes. So a month (43200) is probably still in the realm of sanity.

    But since the cache isn't persisted, if you restart often, you won't benefit as much. And so #149...

    Also, with such long expirations, there should be a command or two to flush the cache, which I will eventually add.

  • _ForgeUser9883694 posted a comment Jul 16, 2014

    We're actually using this for our Bukkit -> Bungee group sync system which means that no players actually pass through the instance that's having issue (not the best solution, but at least it used to work), but have been noticing issues with frequent buycraft purchases as well.

    Maybe the path should be online players -> database fallback -> Mojang? Everybody joining has basically been in the database at some point.

    Edit: Fixed the sync system to be completely local, but still having issues with applying commands to offline players (Buycraft).


    Edited Jul 16, 2014
  • _ForgeUser1494830 posted a comment Jul 16, 2014

    @vemacs: Go

    Thanks, I understand your issue better now.

    A shared cache seems to be the way to go, but I'd rather not overload the use of the entities/memberships tables as that shared cache (see: expiry problem). So a new table is in order.

    I'll see what I can do in the next few days.

  • _ForgeUser1494830 posted a comment Jul 16, 2014

    Dev build #555 (might be a while before it gets built)

    I recommend taking all the usual precautions and then some (test server + test database, backups, etc). I saw some weirdness while testing the MySQL schema update script that went away after I rebuilt the jar. So... yeah.

    Adds a new table named uuidcache. Players logging in or logging out populates this table.

    This database-driven UUID resolver is queried before the Mojang resolver.

    The timeout of the database UUID cache is governed by the uuid-database-cache-ttl option (also hidden). Defaults to 120 minutes. I recommend something much longer until name changes come around.

  • _ForgeUser8721736 posted a comment Jul 17, 2014

    How is the UUID cache handled for flat file permissions data storage? Is a separate SQL storage created for the purposes of the cache?

  • _ForgeUser1494830 posted a comment Jul 18, 2014

    @MinecraftAdmin: Go

    Flat file has no separate UUID cache at this time. If you're using flat file, you most likely aren't sharing instances, so you can just use the normal UUID cache options (uuid-cache-size and uuid-cache-ttl).


To post a comment, please login or register a new account.