-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Version 0.17.0 Release Notes [Preview] #802
Comments
Sometime this or next week I hope to release 0.17. These release notes try to communicate what changed, why and how to migrate code that is impacted by the changes. Please let me know what you feel needs to be added/changed for it to be clearer or more useful. Also, now is the time for any final feedback on the changes in 0.17 before they are released and become the published API. The major changes in this release are:
|
I have a question about Now Of course, the o = observable.map(...).filter(...).take(5)
o.lift(new MyCustomOperator(o)).map(...).subscribe() |
Just because it can't be written in a single line of code doesn't mean that it isn't chained like the others. |
By converting to See a prototype example here: https://gist.github.com/benjchristensen/8367765#file-obsurvable-java-L132 public Obsurvable<T> repeat() {
return from(this).bind(new RepeatOperator<T>());
} Here is a pull request implementing public final static <T1, T2, R> Observable<R> zip(Observable<? extends T1> o1, Observable<? extends T2> o2, final Func2<? super T1, ? super T2, ? extends R> zipFunction) {
return just(new Observable<?>[] { o1, o2 }).lift(new OperatorZip<R>(zipFunction));
} |
It wouldn't take much to allow it being written in a single line. All we need is a simple function/operator that goes For example, if we called it o = observable.map(...).filter(...).take(5).toNestedObservable().lift(new MyCustomOperator()).map(...).subscribe() The implementation of the function would simply be: public Observable<Observable<T>> toNestedObservable() {
return from(this);
} |
Thanks for your clarification. I feel |
We deal with Also, it should be very rare that someone will need to use |
I feel it's not intuitive because, for example, |
If you consider what That's the elegance of |
Thanks for your explanation. Really cleared my confusion. |
Glad it was helpful, and thank you for your involvement and being willing to ask and share your opinion! |
I'm trying to implement the public class OperatorSubscribeOn<T> implements Operator<T, Observable<T>> {
private final Scheduler scheduler;
public OperatorSubscribeOn(Scheduler scheduler) {
this.scheduler = scheduler;
}
@Override
public Subscriber<? super Observable<T>> call(final Subscriber<? super T> subscriber) {
return new Subscriber<Observable<T>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(final Observable<T> o) {
scheduler.schedule(new Action1<Inner>() {
@Override
public void call(final Inner inner) {
if(!inner.isUnsubscribed()) {
o.subscribe(subscriber);
}
}
});
}
};
}
} However, I encounter a problem. I can not dispatch the Is there any way that an |
Just find I can create a Subscriber with a CompositeSubscription to change the |
Yes, a |
Outstanding items I want resolved or completed before releasing include:
public Subscription schedulePeriodically(final Action1<Scheduler.Inner> action, long initialDelay, long period, TimeUnit unit) to public Subscription schedulePeriodically(final Action1<Scheduler.Inner> action, long initialDelay, , TimeUnit unit, long period, TimeUnit unit)
Please let me know if you have things you feel are needed before 0.17 are released. I'd also appreciate insight or help on achieving the above goals. |
@abersnaze After the merge of #836 are you comfortable with "Debug plugin functional (all hooks proven)"? |
Marked "Debug plugin functional (all hooks proven)" as completed as the changes from @abersnaze are merged and we reviewed together and they look good. They resulted in #857 changing the signature to |
"Scheduler.periodicDelay" is done in #856 ... open for debate on whether it should be merged or not. |
"GroupBy functional bugs" is more-or-less done I believe, except for determining whether the |
Other than the final things being worked on, does anyone else have things you feel are needed in 0.17, or that have happened in 0.17 that you disagree with (for objective reasons)? |
Can we have an issue for "Zip with back pressure" with all the requirements so discussions won't detract this issue? |
Here you go: Zip Back-pressure #867 |
I'm not going to hold up 0.17.0 for |
The My only remaining concern is performance for Once I confirm a test (#869 (comment)) I will merge this last pull request and release a candidate (0.17.0-RC1) for testing and if that goes well release the real thing (0.17.0). |
Released 0.17.0-RC1 for testing: https://github.com/Netflix/RxJava/releases/tag/0.17.0-RC1 Starting the canary testing on our end. Once we have proven we can serve our production traffic on this code I will release 0.17.0. I am only merging bug fixes for now before tackling new features and design improvements. |
Verison 0.17.0-RC2 has been released for testing: https://github.com/Netflix/RxJava/releases/tag/0.17.0-RC2 /cc @samuelgruetter @jmhofer @mttkay @daveray for feedback on whether all is well with language adaptors, Android and Swing modules. Testing at Netflix is continuing, I'd appreciate your feedback before calling this version ready for production release due to it's massive changes in subscription and scheduling behavior. |
Of interest, while hunting down the |
As of now I am not aware of any further changes needed for 0.17.0 so I'm looking for bug reports and fixes. |
Thanks @daveray for the confirmation. |
0.17.0 RC6 was just released. Testing in dev is going well though I have not yet been able to canary it in our production environment as we have some yak shaving to do to get it into our production codebase due to the signature changes. They are a side-effect of a hack we did over a year ago when we moved from internal to open source version and that hack has caught up to us with the Is anyone else doing testing to validate this release is working for you? I would particularly be interested in experience from Android developers. |
Ben, I set a day aside today to focus on this. We haven't yet moved to 0.17 |
Looking good so far. Would like to put out a beta with these changes in place to be sure. One thing I had issues with: Observables are not mockable anymore using Mockito, since the More feedback soon. |
Forgot to mention: this might be an IntelliJ issue, but whenever I subscribe a
However, it builds fine on the command line. Anyone else getting this? I think the problem is that a Subscriber is an Observer too. Don't remember exactly how Java handles this, I guess one would assume it picks the most specific signature match at runtime? Anyone else getting this warning? It's a bit annoying, because I actually configured my IDE to display warnings as errors, so the RxJava code is bleeding all over the place. |
Thank you for taking the time to play with it.
That seems very wrong for IntelliJ to do that. Eclipse doesn't have the issue. I'm not sure what we would change since it seems fairly normal to have method overloads such as this.
They were never very good at being mocked anyways. There is a new |
We could eliminate this method: public final Subscription subscribe(Subscriber<? super T> observer) ... and do an And I don't want to delete the If I had to choose between them, I'd rather kill I'd really rather just make IntelliJ not be broken. |
@mttkay Which version of IntelliJ is that? I had similar trouble with the 12.x series, unrelated to RxJava. I think it is (still) caused by the incomplete and/or bogus Java 8 support. |
@akarnokd Do you not see this issue? Are you on 13.x? I'm curious because RxJava (or Android) doesn't involve Java 8 and thus shouldn't be affected by that bug. |
I get the same, but it really does not matter since it compiles fine. I would not change anything for that. |
The once place I get the spurious error is in merge:
|
This is on 13.0.2. It's just a warning, not an error, but still. I actually |
@mttkay This compiler issue was the reason I turned away from IJ to NetBeans; I'm working on a lambda intensive code and got tired IJ complaining about most of it. |
We have a solid proposal from @abersnaze that provides "pause" functionality on More to come in the next few days. |
Does everyone want to wait for Netflix to finish testing this release in prod before officially releasing, or are enough of you content with RC 6 that I should release it and let further improvements come in 0.17.x? |
Any takers on giving a yes/no on whether you feel 0.17.0 RC6 is ready for your production use? |
My production use currently consists of PublishSubject only, so it is a go for me. However, we should consider reimplementing the most-used operations as operators before releasing. |
I've used it in development builds for about a week now and didn't have any We do not use any operators beyond map, mergeMap, cache, publish and +1 |
I've been using it on Android since RC2 for the cgeo development branch and nightly releases. We use So far, everything seems to be working well. |
Great, thank you for your feedback.
@akarnokd I feel that will take far too long and introduce more risk of delaying for another month. The full benefits of the |
We tried to use it, no good so far since there are problems when working with iterables (we need to observe queues and Kafka topics). What makes it worse is that it looks like everything works (observer gets data that seems right) until you start digging. |
Are you referring to back pressure (buffer bloat) or something that was working in 0.16 and no longer works in 0.17? |
@benjchristensen Yes, I guess the top 10 operators with overloads would take a few weeks. Regardless, I would like to start working on the reimplementations en-masse. |
Yes, it will be happening soon. Let's not quite start until we get 0.17.0 out the door and agree upon the coding patterns. I also want to nail down our answer for back pressure. |
Despite not being able to fully validate in our prod environment (for severe yak shaving reasons) I don't want to hold this up any further and believe we have validate enough to move forward. Bugs (which will surely be found) will be fixed in 0.17.x releases along with re-implementaitons of the many operators that are still on the old I'll revise the release notes and release this soon. |
RxJava 0.17.0-RC7 is released. Some small issues arose with debug hooks I want to validate before making this 0.17.0 Release. |
@benjchristensen in the new release notes, can you fix the |
Ha, good catch, just fixed. I wrote the code in an IDE to make sure it compiled, but didn't test that part! |
#0.17.0 Release Notes
Version 0.17.0 contains some significant signature changes that allow us to significantly improve handling of synchronous Observables and simplify Schedulers. Many of the changes have backwards compatible deprecated methods to ease the migration while some are breaking.
The new signatures related to
Observable
in this release are:Also changed is the
Scheduler
interface which is much simpler:This release applies many lessons learned over the past year and seeks to streamline the API before we hit 1.0.
As shown in the code above the changes fall into 2 major sections:
1) Lift/OnSubscribe/Subscriber
Changes that allow unsubscribing from synchronous Observables without needing to add concurrency.
2) Schedulers
Simplification of the
Scheduler
interface and make clearer the concept of "outer" and "inner" Schedulers for recursion.Lift/OnSubscribe/Subscriber
New types
Subscriber
andOnSubscribe
along with the newlift
operator have been added. The reasons and benefits are as follows:1) Synchronous Unsubscribe
RxJava versions up until 0.16.x are unable to unsubscribe from a synchronous Observable such as this:
Subscribing to this
Observable
will always emit all 1,000,000 values even if unsubscribed such as viaoi.take(10)
.Version 0.17.0 fixes this issue by injecting the
Subscription
into theOnSubscribe
function to allow code like this:Subscribing to this will now correctly only emit 10
onNext
and unsubscribe:Or the new
Subscriber
type can be used and theSubscriber
itself canunsubscribe
:2) Custom Operator Chaining
Because Java doesn't support extension methods, the only approach to applying custom operators without getting them added to
rx.Observable
is using static methods. This has meant code like this:In reality we want:
Using the newly added
lift
we can get quite close to this:Here is how the proposed
lift
method looks if all operators were applied with it:Along with the
lift
function comes a newOperator
signature:All operator implementations in the
rx.operators
package will over time be migrated to this new signature.3) Simpler Operator Implementations
The
lift
operator injects the necessaryObserver
andSubscription
instances (via the newSubscriber
type) and eliminates (for most use cases) the need for manual subscription management. Because theSubscription
is available in-scope there are no awkward coding patterns needed for creating aSubscription
, closing over it and returning and taking into account synchronous vs asynchronous.For example, the body of
fromIterable
is simply:The
take
operator is:4) Recursion/Loop Performance
The
fromIterable
use case is 20x faster when implemented as a loop instead of recursive scheduler (see a18b8c1).Several places we can remove recursive scheduling used originally for unsubscribe support and use a loop instead.
Schedulers
Schedulers were greatly simplified to a design based around
Action1<Inner>
.This design change originated from three findings:
To solve this the new design explicitly has the outer
Scheduler
and thenScheduler.Inner
for recursion.In this new design all state passing signatures have been removed. This was determined while implementing a
RemoteScheduler
that attempted to useobserveOn
to transition execution from one machine to another. This does not work because of the requirement for serializing/deserializing the state of the entire execution stack. Migration of work over the network has been bound to be better suited to explicit boundaries established by Subjects. Thus, the complications within the Schedulers are unnecessary.This new design removes all but the essential and simplest methods.
This new design applies similar principles as done with
lift
/create
/OnSubscribe
/Subscriber
and injects theSubscription
via theInner
interface so a running task can checkisUnsubscribed()
.WIth this new design, the simplest execution of a single task is:
Recursion is easily invoked:
The use of
Action1<Inner>
on both the outer and inner levels makes it so recursion that refer tothis
and it works easily.Similar to the new
lift
/create
pattern withSubscriber
theInner
is also aSubscription
so it allows efficient loops withunsubscribe
support:An action can now
unsubscribe
theScheduler.Inner
:Typically just stopping is sufficient:
but if other work in other tasks is being done and you want to unsubscribe conditionally you could:
and the recursion can be delayed:
The methods on the
Inner
never return aSubscription
because they are always a single thread/event-loop/actor/etc and controlled by theSubscription
returned by the initialScheduler.schedule
method. This is part of clarifying the contract.Thus an
unsubscribe
controlled from the outside would be done like this:Migration Path
1) Lift/OnSubscribe/Subscriber
The
lift
function will not be used by most and is additive so will not affect backwards compatibility. TheSubscriber
type is also additive and for most use cases does not need to be used directly, theObserver
interface can continue being used.The previous
create(OnSubscribeFunc f)
signature has been deprecated so code will work but now have warnings. Please begin migrating code as this will be deleted prior to the 1.0 release.Code such as this:
should change to this:
If concurrency was being injected:
you may no longer need it and can implement like this instead:
or can just simplify the
Subscription
management:or use a
Scheduler
:or use
subscribeOn
which now works to make synchronousObservables
async while supportingunsubscribe
(this didn't work before):2) Schedulers
Custom
Scheduler
implementations will need to be re-implemented and any direct use of theScheduler
interface will also need to be updated.3) Subscription
If you have custom
Subscription
implementations you will see they now need anisUnsubscribed()
method.You can either add this method, or wrap your function using
Subscriptions.create
and it will handle theisUnsubscribed
behavior and execute your function whenunsubscribe()
is called.The Future...
This is hopefully the last of the major refactors to rxjava-core and we're approaching version 1.0. We have most if not all operators from Rx.Net that we want or intend to port. We think we have got the
create
/subscribe
signatures as we want and theSubscription
andScheduler
interfaces are now clean.We need to improve on some of the
Subject
implementations still, particularlyReplaySubject
. We are beginning to focus after this release on cleaning up all of the operator implementations, stabilizing, fixing bugs and performance tuning.We appreciate your usage, feedback and contributions and hope the library is creating value for you!
The text was updated successfully, but these errors were encountered: