Closed akarnokd closed 5 years ago
I'd like to propose making takeUntil
and similar variants take a Maybe
. The contract is that it takes until the first emission, which is the same contract as a Maybe
.
But why? A Single seems more appropriate contract-wise, but at that point I'd generalize it back to Observable which already exists. The need for those overloads is actually a need for polymorphic stream types instead.
On Tue, Oct 3, 2017 at 5:30 AM Zac Sweers notifications@github.com wrote:
I'd like to propose making takeUntil and similar variants take a Maybe. The contract is that it takes until the first emission, which is the same contract as a Maybe.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ReactiveX/RxJava/issues/5622#issuecomment-333789357, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEERrIqc6C7UuvAoQI57Iap-Evhe9xks5sof67gaJpZM4Pj9aM .
I guess it depends. Sometimes you takeUntil() something that may or may not actually emit, like many lifecycle handling patterns do
But single isn't required to emit.
On Tue, Oct 3, 2017 at 5:15 PM Zac Sweers notifications@github.com wrote:
I guess it depends. Sometimes you takeUntil() something that may or may not actually emit, like many lifecycle handling patterns do
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/ReactiveX/RxJava/issues/5622#issuecomment-333980979, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEa77DEhI-gYqHRXDoLsH2myadDpHks5soqP9gaJpZM4Pj9aM .
I suppose this is true, if the source stream completes it just disposes the single?
If we decide to keep target version #5620 lower than Java 8 then:
throws Exception
from io.reactivex.functions.Function#apply()
method.else
io.reactivex.functions.Function
and replace it with java.util.function.Function
Sounds good?
@artem-zinnatullin Why? Adding the throws Exception
was well worth the effort. In fact, the idea was to make it throws Throwable
in v3. Btw, the topic warrants its own issue/discussion.
Ah damn checked exceptions. @akarnokd, you're right of course.
For rx chains it's good that Function
declares exception and probably should declare Throwable
, the use case I was dealing with today is when in our Java code we needed to call function.apply()
and had to wrap it in a try-catch. Kotlin 😿
Single.toCompletable
to Single.ignoreElement
to be consistent with the other types.Isn't that just a new overload and deprecation that can be done as part of 2.x?
Well, the alias could be added to 2.x but then toCompletable
should not be in 3.x. Should we start aliasing and deprecating these types of methods in v2 so that users get better prepared for changes in 3.x?
I think the general assumption is that everything which is deprecated will be removed in the next major version, yes. Plus it delays the need to even require that a 3.x exist.
In 3.x I'd like to make upstream work more precise (across networks for instance) as discussed in #5077, and do it without adding extra operators. For example, the first
operator requests Long.MAX_VALUE
of upstream as a perf optimisation that I reckon we can do without.
AsyncSubject.getValues()
AsyncProcessor.getValues()
Will .getValue()
stay while .getValues()
is removed ?
Or do you plan to remove the ability to get any value(s) out of a Subject / Processor.
@cerisier getValue()
methods are supposed to be already present only on the relevant types.
Will 3.x have different package name from 2.x?
When I follow the package naming history of RxJava 2 in #3173, it seems that the final version of package name has changed to io.reactivex from 1.x's rx, but not to include version number eventually.
As described by Jake Wharton in one of the comments in the above issue, versioned package were somewhat of a rarity back in Aug 2015 when the discussion was active, but I believe some of the popular libraries have adopted the policy, mainly to support co-existence of different incompatible versions of libraries. Retrofit and OkHttp did for 2.0 and 3.0, respectively, as described in https://jakewharton.com/java-interoperability-policy-for-major-version-updates/.
Probably it's too early to ask this question, but I noticed that 3.0 milestone is due by end of 2019 and so many RxJava consumers who are library authors will want to know the direction. Please notify me if this belongs to a separate issue, and I will post a new issue. Thanks in advance :)
2.x was had the complete architecture remade so it warranted a separate package. 3.x will be very likely mostly API breaking changes but the package will remain io.reactivex
and users switching to it may only have to adjust to the API changes with certain operators.
That sounds like a really bad idea!
I don't see any reason to have 2.x and 3.x live side-by-side. The top reason for 3.x to exist is to fix the API mistakes.
It makes practical migration impossible for large-scale projects using libraries built on Rx and discourages its use in the future.
Consumers do not voluntarily let 2.x and 3.x live side-by-side. It will be due to incompatible versions of a common library (such as RxJava, networking, or json parsing library) used by both libraries and consumers.
Renaming packages when updating major version makes migration period really smooth and incremental with least amount of headache for both. If this isn't the case, the only choice left to library authors will be to use no library at all and writing everything from scratch, which they really don't want to.
There is one way to find out: make the breaking changes and see how much code breaks in the popular libraries. Unlike RxJava 2, RxJava 3 would be a drop-in replacement to RxJava 2, minus a few API adjustments.
That is quite a user-hostile approach.
Also "drop-in replacement" and "a few API adjustments" are not compatible. It's either a drop-in replacement that's binary compatible OR it requires API adjustments requiring all libraries update before you can.
How many libraries are using the operators in this list? Why are they using blockingGet
in non-test code, for example? Do you replace a dependent libraries without recompiling/retesting the host library/application?
I'm almost certain RxAndroid, RxRelay, RxBinding, RxSharedPreferences either won't have to change or would need a simple recompile if the Rx functional interfaces get widened to throws Throwable
. There won't be any architectural change with 3.x, create
and X.subscribeActual
will remain the same, as will fromCallable
and the Scheduler/Worker API. JDK support will also remain 6.
So I don't believe the set of breaking changes proposed will do more than just a small inconvenience. I'll personally take the time and post PRs to any open-source project that depended on the old signatures and update them to version 3 usage.
Consumers do not voluntarily let 2.x and 3.x live side-by-side. It will be due to incompatible versions of a common library (such as RxJava, networking, or json parsing library) used by both libraries and consumers.
Do you think 3rd party library authors are willing to support 2 versions, one for 2.x and one for 3.x, at the same time for an overlapping duration? What if the signature changes do not affect them at all?
Let's turn it around. Why do you think I have the time or will to support two versions, again? Why would I have to spend time answering SO questions/issue questions about why Schedulers.io()
no longer compiles because the OP forgot to change the import to like io.reactivex.rxjava3
?
RxJava's API has to improve, as the minor inconveniences turn into major ones over time. Also I'm pretty positive about the ecosystem's flexibility; they will move forward as well, sooner or later.
All this said, here is the deal:
io.reactivex.rxjava3
.Keeping the same package structure with different maven coordinates will cause classpath collisions right?
On Tue, Feb 19, 2019 at 2:13 PM David Karnok notifications@github.com wrote:
How many libraries are using the operators in this list? Why are they using blockingGet in non-test code, for example? Do you replace a dependent libraries without recompiling/retesting the host library/application?
I'm almost certain RxAndroid, RxRelay, RxBinding, RxSharedPreferences either won't have to change or would need a simple recompile if the Rx functional interfaces get widened to throws Throwable. There won't be any architectural change with 3.x, create and X.subscribeActual will remain the same, as will fromCallable and the Scheduler/Worker API. JDK support will also remain 6.
So I don't believe the set of breaking changes proposed will do more than just a small inconvenience. I'll personally take the time and post PRs to any open-source project that depended on the old signatures and update them to version 3 usage.
Consumers do not voluntarily let 2.x and 3.x live side-by-side. It will be due to incompatible versions of a common library (such as RxJava, networking, or json parsing library) used by both libraries and consumers.
Do you think 3rd party library authors are willing to support 2 versions, one for 2.x and one for 3.x, at the same time for an overlapping duration? What if the signature changes do not affect them at all?
Let's turn it around. Why do you think I have the time or will to support two versions, again? Why would I have to spend time answering SO questions/issue questions about why Schedulers.io() no longer compiles because the OP forgot to change the import to like io.reactivex.rxjava3?
RxJava's API has to improve, as the minor inconveniences turn into major ones over time. Also I'm pretty positive about the ecosystem's flexibility; they will move forward as well, sooner or later.
All this said, here is the deal:
- Fix up the API and release RxJava 3 with the same package structure but updated maven address io.reactivex.rxjava3.
- Stop adding new features to RxJava 2, only bugfixes and significant JavaDocs updates.
- Keep supporting RxJava 2 this way for 1.5 years tops.
- Retire RxJava 2.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ReactiveX/RxJava/issues/5622#issuecomment-465142759, or mute the thread https://github.com/notifications/unsubscribe-auth/ABTEvlMOKnk5nMgNpfhuP2wGPjEyXSlmks5vPAZwgaJpZM4Pj9aM .
exclude group: 'io.reactivex.rxjava2', module: 'rxjava'
or don't upgrade until the dependent libraries upgrade? Let's turn it around: we release under the new package structure -> almost no libraries for months.
Not sure how other libraries match the releases of RxJava 2 at the moment; RxAndroid does not follow for sure. Mine do follow.
Also for the throws Throwable
. According to the spec: they are checked at compile time only.
In addition, widening seems to be okay too for compile time:
public class ThrowsSubclass {
interface F {
void m() throws Throwable; // was throws Exception
}
public static void main(String[] args) {
new F() {
@Override
public void m() throws Exception {
}
};
}
}
Libraries don't need to match the releases of RxJava and there's no reason to do this because of binary compatibility and dependency resolvers. If anything, libraries should be doing the opposite and expressing the minimum version they work with to not force behavior changes on their consumers unless desired.
To answer your specific questions...
How many libraries are using the operators in this list?
It's impossible to know, of course, but it's guaranteed to be more than zero.
Why are they using
blockingGet
in non-test code, for example?
This is a weird example considering it's the least-used and least-useful of the bunch. So while it might be zero, the others are non-zero.
Do you replace a dependent libraries without recompiling/retesting the host library/application?
Of course. Transitive dependency resolution guarantees this to happen with libraries. It's why we have jars and why Java does linking at runtime instead of statically at compile-time.
I'm almost certain RxAndroid, RxRelay, RxBinding, RxSharedPreferences either won't have to change or would need a simple recompile if the Rx functional interfaces get widened to
throws Throwable
.
While this represents a popular set of libraries for Android, in the scope of the RxJava ecosystem it's tiny. And this specific change is only source-incompatible, not binary-incompatible, so it's not as worrying as the API changes.
There won't be any architectural change with 3.x,
create
andX.subscribeActual
will remain the same, as willfromCallable
and the Scheduler/Worker API. JDK support will also remain 6.
This only reaffirms my belief that there's no need for a version 3 right now. A useful RxJava 3 to me should be built against j.u.c.Flow and architected in a way to take advantage of Project Loom when it arrives.
Do you think 3rd party library authors are willing to support 2 versions, one for 2.x and one for 3.x, at the same time for an overlapping duration? What if the signature changes do not affect them at all?
Some did this for 1.x and 2.x, yes. But the interop library actually means you're not even required to do it. The consumer of libraries could upgrade piecemeal by slowing moving the interop barrier across their application until the need for it was removed.
Why do you think I have the time or will to support two versions, again?
I don't even want an RxJava 3 so I'm not asking you to. But beyond that, there's plenty of people around this project that can and will help.
Later on in the post your plan outlines that you're already going to support both though so based on that you seem to think you have the time.
Why would I have to spend time answering SO questions/issue questions about why
Schedulers.io()
no longer compiles because the OP forgot to change the import to likeio.reactivex.rxjava3
?
Are these going to number greater or less than the NoSuchMethodError posts? And the answer easier or harder to explain? But, again, there's a whole community that can help do this and it's the point of StackOverflow's whole system.
RxJava's API has to improve
Sure, but it needs some carrot balanced with the stick.
Right now the value proposition of 3.x is practically non-existent for consumers. We get a few warts fixed, sure, but at a cost that disproportional to the benefit.
as the minor inconveniences turn into major ones over time.
On a long enough timeline they might, but are these really at that point? None of the proposed changes unlock some fundamental potential that's missing.
Also I'm pretty positive about the ecosystem's flexibility; they will move forward as well, sooner or later.
I am too. Except actions like this will actually force a subset to alternate solutions which aren't hostile to their builds which is unfortunate. Or they'll simply stay on 2.x.
we release under the new package structure -> almost no libraries for months.
Does this matter? It doesn't affect this library. At least in this case when consumers want to upgrade they can do so incrementally without a flag day where everything needs to change at once.
I want to see a 3.x that moves the goal posts for what a reactive library can be and makes Reactor look obsolete. Not something that fixes a few dings in the paint of its bumper.
@JakeWharton I understand your arguments, but as you put it "Does this matter? It doesn't affect this library". So if 3.x is created, how does it affect existing libraries and their maintainers?
I'm trying to understand the underlying concerns here. If nobody supports it -> nobody upgrades -> 3.x dies out. If some high-profile projects support it -> push others to upgrade -> 3.x thrives eventually. Every supplier upgrades -> clients upgrade -> 3.x thrives. Loom/coroutines win the market -> mostly nobody cares about RxJava ever again. Either way, creating 3.x does not delete 2.x and all those depending on 2.x.
Are you worried about split community? Expect constant nag on projects to upgrade to RxJava 3? Are you worried about RxJava 2 support drying out?
I want to see a 3.x that moves the goal posts for what a reactive library can be and makes Reactor look obsolete.
Reactor is targeting the desktop/server/cloud world and as such, it can always be on the edge of the tech curve. Also let me state that RxJava did not and does not compete with Reactor.
We are held back by Android's Java 6 baseline. I'd be quite happy if that would bump to Java 9 where I'm more willing to repackage RxJava - a very requirement for modules to work properly anyway as we'd have to move code from io.reactivex
to io.reactivex.publishers
or something due to how modules must be organized. At that point everything already broke so everybody will suffer the same.
Is RxJava held back by that? The Android community had to fight for 2.x to support Java 6 instead of being Java 8+. I'm prepared to argue for 3.x to leave Android far, far behind. We can take care of ourselves by maintaining 2.x indefinitely. Most Java libraries should start to consider abandoning Android as the Java and JVM ecosystem really kicks into high gear and Android shows no sign of keeping pace at any reasonable timeline based on what's happening (or not) in AOSP.
The Android community had to fight for 2.x to support Java 6 instead of being Java 8+.
I remember it differently: #3450. I don't see any hard fights there, but correct me if I, or the other maintainers at the time, happen to have resisted somewhere else regarding the support level. I even put in the extra effort and made RxJava 2 Java 6 compatible again, undoing some of my own Java 8 related work in the process.
Android shows no sign of keeping pace at any reasonable timeline
Kotlin has extension methods which makes the need for breaking changes obsolete there, hence 3.x is unnecessary. Just add a new extension method with the correct return type and hide the "bad" methods. Also Kotlin coroutines make one-shot async processing convenient enough most of the time that RxJava is abandoned en-masse already. They don't care what 3.x breaks.
As an Android developer, I'd be fine with sticking on RxJava2 until there was an actual need for a major version bump. And neither I, nor anyone I know have abandoned RxJava for coroutines when the use case calls for it, which is often. Some of us are quite bought-in to rx.
I really wouldn't mind seeing RxJava (or a reactive implementation) built on coroutines but that's more for ease of implementing operators (which isn't so bad with Kotlin because of extensions). I guess it would just be cool.
For 3.x I think it would be nice to see PublishSubject.create()
return what is the 2.x equivalent of PublishSubject.create().toSerialized()
. Unserialized access of PublishSubject
s seems to turn up a lot as the cause of people's problems. An additional factory method for the performant but serialize access yourself version could be added - e.g. PublishSubject.createRequiresSerialization()
.
Closing via #6514, #6516 and #6517.
This issue collects the API changes proposed for 3.x: unused operators and overloads, mistakes in signatures, etc.
Flowable.subscribe(/* 4 args */)
withConsumer<? super Subscription>
-> #6517Observable.subscribe(/* 4 args */)
withConsumer<? super Disposable>
-> #6517Completable.blockingGet()
signature -> #6517Maybe.defaultIfEmpty
to returnSingle
. -> #6517X.to()
to use dedicated non-generic functional type which then can be implemented by a single class for multiple base types. (#5654) -> #6514BehaviorSubject.getValues()
-> #6516BehaviorProcessor.getValues()
-> #6516Single.toCompletable
toSingle.ignoreElement
to be consistent with the other types. -> #6517AsyncSubject.getValues()
-> #6516AsyncProcessor.getValues()
-> #6516