ReactiveX / RxJava

RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Apache License 2.0
47.82k stars 7.6k forks source link

Support for Experimental Ideas in Major Version Lifecycle #1824

Closed benjchristensen closed 9 years ago

benjchristensen commented 9 years ago

In a major version lifecycle (such as 1.x) there will still be a desire to add things over time and often this requires experimentation and feedback. I'd like to explore the idea of having experimental or beta features shipped in the released code.

Guava does this with an @Beta annotation. Perhaps we should also adopt @Beta or @Experimental to mark signatures that have not stabilized and may change?

It would be the opposite of @Deprecated which will be used for things we determine to be mistakes, which I'm sure we will still have made despite the long road to 1.0 and effort to stabilize the API.

Large experimental ideas should be done in separate projects such as https://github.com/ReactiveX/RxJavaParallel, but others are either too small for that or it is too difficult to do without being in core, such as exploring an rx.Future type that integrates with Observable.

I'd appreciate feedback on how to handle experiemental/beta work in a production released library.

headinthebox commented 9 years ago

In .NET we experimented with separate experimental and stable releases, but that was too confusing. The dual of @depricated makes a lot of sense.

zsxwing commented 9 years ago

+1. Both @Beta and @Experimental are good to me.

benjchristensen commented 9 years ago

What would differentiate @Beta and @Experimental. Would @Beta be something we think is ready but just need time and testing whereas @Experimental is something to not be trusted at all?

benjchristensen commented 9 years ago

It seems that this Guava code is a good model to follow: https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/annotations/Beta.java

What package should this live in, a new rx.annotations or somewhere else? It can't be inside rx.internal as this is supposed to be public.

/*
 * Copyright (C) 2010 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Originally from https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/annotations/Beta.java
 */
package rx.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Signifies that a public API (public class, method or field) is subject to
 * incompatible changes, or even removal, in a future release. An API bearing
 * this annotation is exempt from any compatibility guarantees made by its
 * containing library. Note that the presence of this annotation implies nothing
 * about the quality or performance of the API in question, only the fact that
 * it is not "API-frozen."
 *
 * <p>It is generally safe for <i>applications</i> to depend on beta APIs, at
 * the cost of some extra work during upgrades. However it is generally
 * inadvisable for <i>libraries</i> (which get included on users' CLASSPATHs,
 * outside the library developers' control) to do so.
 *
@Retention(RetentionPolicy.CLASS)
@Target({
    ElementType.ANNOTATION_TYPE,
    ElementType.CONSTRUCTOR,
    ElementType.FIELD,
    ElementType.METHOD,
    ElementType.TYPE})
@Documented
@GwtCompatible
@Beta
public @interface Beta {}
benjchristensen commented 9 years ago

I have updated the README to document the lifecycle and versioning policies. Are these acceptable?

https://github.com/ReactiveX/RxJava/blob/1.x/README.md#versioning

Versioning

Version 1.x is now a stable API and will be supported for several years.

Minor 1.x increments (such as 1.1, 1.2, etc) will occur when non-trivial new functionality is added or significant enhancements or bug fixes occur that may have behavioral changes that may affect some edge cases (such as dependence on behavior resulting from a bug). An example of an enhancement that would classify as this is adding reactive pull backpressure support to an operator that previously did not support it. This should be backwards compatible but does behave differently.

Patch 1.x.y increments (such as 1.0.0 -> 1.0.1, 1.3.1 -> 1.3.2, etc) will occur for bug fixes and trivial functionality (like adding a method overload). New functionality marked with an @Beta or @Experimental annotation can also be added in patch releases to allow rapid exploration and iteration of unstable new functionality.

@Beta

APIs marked with the @Beta annotation at the class or method level are subject to change. They can be modified in any way, or even removed, at any time. If your code is a library itself (i.e. it is used on the CLASSPATH of users outside your own control), you should not use beta APIs, unless you repackage them (e.g. using ProGuard, shading, etc).

@Experimental

APIs marked with the @Experimental annotation at the class or method level will almost certainly change. They can be modified in any way, or even removed, at any time. You should not use or rely on them in any production code. They are purely to allow broad testing and feedback.

@Deprecated

APIs marked with the @Deprecated annotation at the class or method level will remain supported until the next major release but it is recommended to stop using them.

benjchristensen commented 9 years ago

Does https://github.com/ReactiveX/RxJava/pull/1905 look good to you all?

daschl commented 9 years ago

Interesting approach! We decided to split up audience and stability: https://github.com/couchbase/couchbase-jvm-core/tree/master/src/main/java/com/couchbase/client/core/annotations

Where the stabilites are experimental, uncomitted and comitted. I'm +1 on the proposed ones here too. I think it is more important that they are used consistently :)

benjchristensen commented 9 years ago

The audience annotation is interesting. We ended up using the rx.internal.* packaging and excluding those from the Javadocs.

Thanks for weighing in on this. And definitely consistent use is important.

benjchristensen commented 9 years ago

Merged based on confirmation from @daschl and @akarnokd