Metadata System Benefits

Discussion in 'Plugin Development' started by EdGruberman, Apr 6, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    EdGruberman Retired Staff

  2. Offline


    The first thing I thought of was that the easiest way to make all plugins use the same Java class would be to include it in Bukkit (somewhere).

    But then you have the problem of adding things in there. The plugins can't use them until they get into Bukkit, so it's a bit of a chicken-and-egg problem there.

    Additionally, some things may be pretty hard to define.
    If LWC wants to protect a single block or a few blocks, it'll probably be fine to have a ProtectedBlock class or something like that.. but if WorldGuard wants to use that, you may have a scaling problem. That is a horrible example and I feel bad for writing it.
    TheGreenGamerHD likes this.
  3. Offline

    ZeusAllMighty11 Retired Staff


    I actually know your example, and I understand it. If one plugin like WorldGuard controls the Metadata for a block in a protected region, marking it protected... what if another plugin wants to access it, like CoreProtect to check for a grief but it also uses the Metadata -- conflict??

    I really REALLY like this idea, I just don't fully understand the true potential of it, and how to set aside conflicts like so ^

    Edit: Just read over the comments you guys had on Github. I don't see why you had to consider junior developers and using this as an example of a bad practice. Hmm, but all aside I truly do believe that this is much more fluent to use instead of a 3rd party api or library.
  4. Offline


    (I'm playing both sides of the argument here)

    So, a bit of background: With the "API provider" pattern generally some interface library exists, and then makers of various plugins write something like (as in the checking whether a block is protected example) LWCProtectionChecker implements ProtectionChecker where ProtectionChecker is imported from the interface library. Vault is an example of that, except that all of the implementations of the interfaces are actually inside of Vault itself, so it doesn't really show how this would work in a third party sort of way.

    Also, I didn't mean to diss junior developers, but the fact of the matter is that using third party jars can get complex. The problem is with some unclarity on how people should embed third party libraries. For example, most of the time when you embed a third party library you put it in the jar. (In maven terms, it's <scope>compile</scope>) You also are highly encouraged to shade the included classes so that your copy of the library doesn't conflict with embedded copies that may exist in other plugins (different versions maybe)

    However, with coding to an interface provider plugin, you want to do it completely different. You want to use it as a linking dependency and not embed the classes (This way the server admin can install an updated version). In maven terms, this is the <scope>provided</scope> dependency. Also, when using a 3rd party library like this, you don't shade it, as you want to make sure you're using the authoritative version of the class, not an embedded (possibly older) copy.

    If everyone used an advanced build tool like maven, it'd be a matter of simple training. But this is an open source community, everyone uses what they want, and most people just sort of throw it all together and pray it works.

    So there's the main headaches with API interface plugins there. Now I'll argue for the opposite side, why metadata can be problematic.

    So Metadata, while it eliminates the initial set-up and dependencies, has its own issues. Say we had a metadata value called "allowedAccess" which listed the players who could access a world. One guy defines it in the contract as a Set<String> while some other guy defines it's a Set<UUID> (or something like this), and some one else does a Map<String, Boolean>.

    While you can differentiate the Set from the Map using instanceof checks, due to type erasure there's no way to know whether the Set is actually a Set<String> or a Set<UUID>. The only way would be to check each element on iteration, or write code in a way that minimizes assumptions. This basically results in a lot of isinstance checking, and possibly can also involve unchecked casting. These are just a small snapshot of the headaches involved.

    So to sum it up in a TL;DR form
    Formal API advantages: type-safe, clear API
    Formal API disadvantages: more jars for server managers, complicated for developers

    Metadata advantages: Super easy to start using, no set-up, no additional jars needed.
    Metadata disadvantages: Not type-safe, provides un-clear contract. Possibly doesn't cover all the things an API might.
  5. Offline

    ZeusAllMighty11 Retired Staff


    Well is there an issue where you can't have both the Metadata, while continuing to use, for example, Vault?
  6. Offline


    the metadata is easy to use instead of hashmaps, an have the advantage that the data is lost when the item despawn, so you dont need to remove it by your own, this way you dont create memory leaks by storing thousands of arrows to see what arrow hits the ground to summon ligthing or something else
  7. Offline


    This is actually incorrect, the memory is only truly cleared when it's explicitly removed or the server is shut down. That said there is a small memory savings on LazyMetadataValue when it expires its cached value (based on CacheStrategy) but the bulk of the memory is kept active anyway (the key, the MetadataValue reference/object, the reference to the owning plugin, etc.

    Object lifecycle is actually a huge problem with the metadata system though it has improved slightly in 1.5.1 as many elements are keyed on the UUID instead of the id which is transient, but it still remains that the metadata is never truly cleared in a typical setup.

    Well we already have metadata and can also still use concrete API's like vault, the issue in question was with a ticket I have which would expand the metadata system into a dispatch system, which solves some but not all of the object lifecycle and scope locality issues with metadata (at least, it makes it easier to track and manage as you'd only need to track it after a request). The argument being presented by EdGruberman is that this change encourages bad design and therefore should not be implemented.
  8. Offline


    using the metadata, you can save the groups a player is in without relaying on 3rd party libraries
Thread Status:
Not open for further replies.

Share This Page