java-manta icon indicating copy to clipboard operation
java-manta copied to clipboard

clarify version stability and api surface area

Open cburroughs opened this issue 8 years ago • 5 comments
trafficstars

From the CHANGELOG "this project aims to adhere to Semantic Versioning". However, that leaves open the questions of what exactly the public api is. Is it all classes that happened to be public? All classes exposed via MantaClient? Everything a "reasonable user" would use? We will also sometimes haphazardly have documentation that say a whole module (ie benchmarks) is not a stable public contract.

This has come up with reviews where we have reasonable through how each class is exposed. That easy to mess up and unfun to repeat on each review. As this library is used more it becomes harder to make the kind of sweeping changes we did in 3.0.0, so we need to create space for organic growth.

In java-http-signature we have deprecated a significant number of methods, but not yet had a release that removed them. java-manta is significantly larger with (as of this writing) 131 non-test classes in the primary module.

Some related approaches:

  • https://illumos.org/man/5/attributes
  • https://cwiki.apache.org/confluence/display/FLINK/Stability+Annotations
  • https://github.com/google/guava/wiki/PhilosophyExplained (Notably @Beta)
  • This hadoop thing: https://hadoop.apache.org/docs/r2.7.1/api/org/apache/hadoop/classification/InterfaceAudience.html

Proposal:

  • Add a @Public annotation to the classes that form the public consumed API of the application. For example, MantaClient and exceptions. I am unsure of the merits of also having an @Internal annotation, and thus mandating that every class have an annotation. I think I lean slightly towards having both so it is harder for developers to make a mistake.
  • Next time we add a significant new feature that is likely to evolve (like the jobs multi-part upload) we should @Beta it (or something like that).
  • Sometime soon (after MPU is "officially" available?), we should take a pass at deprecating warts in 3.x java-manta.
  • If needed use we should totally use @VisibleForTesting or similar.
  • Add a note to the readme on which modules are internal, even if obvious (benchmarks).

NOTE: @Stable will likely be an (internal?) jdk9 annotation, so that might not be the best word choice.

cburroughs avatar Aug 18 '17 18:08 cburroughs

Having been on the implementing side for years, I would assume that anything that is public has an assumption of stability from an API contract standpoint. However, if you are incrementing minor versions, there is an expectation that the behavior may subtly change. With major version changes, the expectation is that some portion of the API will change, but not like 80%. One should be able to catch major version incompatibilities via compilation errors.

dekobon avatar Aug 29 '17 21:08 dekobon

I would assume that anything that is public has an assumption of stability from an API contract standpoint

As a consumer of libraries that is my expectation as well. If the class is public then I can use it. I'll even extend java.lang.String if I want to!

But as library developer, I would not want people to depend on com.joyent.manta.util.ConcurrentWeakIdentityHashMap or com.joyent.manta.client.multipart.EncryptionState.

cburroughs avatar Aug 30 '17 14:08 cburroughs

https://docs.google.com/spreadsheets/d/1lly891zfckkYJfV6nfbBvC2flFsUu9Nya2bqF7F07zw/edit#

I went class by class and took a stab at what this might look like. I think my largest take away was just how broad the api surface area is.

(I think I now lean slightly towards having an @Internal and letting public classes just be public like anyone would assume by default.)

cburroughs avatar Aug 31 '17 17:08 cburroughs

Is the primary issue here that there are classes which should be package-private but need to be public to work across package boundaries?

An annotation for such classes might be valuable but I'd be hesitant to add annotations to every class that reaffirming that the class is public (and doing so indefinitely for every new class) without a clear benefit.

tjcelaya avatar Aug 31 '17 20:08 tjcelaya

Is the primary issue here that there are classes which should be package-private but need to be public to work across package boundaries?

Yes I think that's a good way to put it. I at least have the habit of typing public by default, so it is also possible that some of those "Internal" classes could be package-private.

cburroughs avatar Sep 01 '17 14:09 cburroughs