Skip to content

What is the recommended approach for @ObsoleteCoroutinesApi #632

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

Closed
jcornaz opened this issue Sep 28, 2018 · 17 comments
Closed

What is the recommended approach for @ObsoleteCoroutinesApi #632

jcornaz opened this issue Sep 28, 2018 · 17 comments

Comments

@jcornaz
Copy link
Contributor

jcornaz commented Sep 28, 2018

Version 0.27.0 marked all channel operators with @ObsoleteCoroutinesApi saying:

This API has serious known flaws and will be replaced with a better alternative in the nearest releases.

My question here is: What is the recommended approach while waiting for the better alternative in the nearest releases?

Should we stop using channel operators?
Should we migrate existing code for an alternative technology (like RxJava) in the meantime?

@elizarov
Copy link
Contributor

From the point of usage ObsoleteCoroutinesApi is just like experimental. The different is in intent. When API is experimental it might change or might graduate as is. For obsolete API we already know that there are problems with designs that will force us to deprecated this API in the future when we have a better replacement.

Right now there is no replacement for channel operations, so you have no choice but continue using them. However, we plan to replace them with mechanism based on lazy/cold streams (#254) in the future, which will get you much better performance.

@jcornaz
Copy link
Contributor Author

jcornaz commented Sep 28, 2018

Thanks @elizarov.

you have no choice but continue using them

One could use RxJava or any other reactive stream.

we plan to replace them with mechanism based on lazy/cold streams (#254) in the future

Will we get migration aid?

which will get you much better performance.

Glad to hear it. Even if I haven't been able to suffer any noticeable performance flaws so far.

@elizarov
Copy link
Contributor

Obsolete is like experimental in this sense. There will be migration.

@matejdro
Copy link

matejdro commented Nov 2, 2018

I wonder how good an idea is to mark API as obsolete before offering any alternative?

This just forces anyone to put suppress warnings annotation everywhere when using the API. It's not like I can just stop using operators, apart from switching away from channels to RX (like jcornaz suggested), which I don't want.

@qwwdfsad
Copy link
Collaborator

qwwdfsad commented Nov 5, 2018

I wonder how good an idea is to mark API as obsolete before offering any alternative?

KDoc to annotation literally says that this is the deprecated API which has no replacement or alternative.
The other options are @Deprecated (and a deprecation without replacement is even worse than experimental), and @Experimental which may give a false feeling that this API is good and may become stable in the future.

But I think we can improve documentation here. "Obsolete" means that you can still use it for a while, but it's better not to expose it to users (e.g. if you write some kind of a library or interop layer) or not to build your entire architecture on top of such primitive (e.g. actor)

@matejdro
Copy link

matejdro commented Nov 5, 2018

KDoc to annotation literally says that this is the deprecated API which has no replacement or alternative

I do realize that, but that still does not stop IntelliJ from painting my code yellow or compiler from spewing warnings for no reason as there is no alternative to using this apart from suppressing the warning which feels bad.

@pchmielowski
Copy link

@matejdro You can wrap the channel API (just the parts of it which you are using) by your own methods. Then you'll suppress the warning in the one place only.
Now, the migration to the new API which will replace channels in the future will be much easier.

@jcornaz
Copy link
Contributor Author

jcornaz commented Mar 7, 2019

@pchmielowski No need to wrap all method of the API just to make the warning disappear.

If you want to suppress all the warnings in your project just pass -Xuse-experimental=kotlinx.coroutines.ObsoleteCoroutinesApi to the compiler.

Here is an example with Gradle:

tasks.withType(KotlinCompile::class) {
  kotlinOptions {   
    freeCompilerArgs += listOf(
      "-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi",
      "-Xuse-experimental=kotlinx.coroutines.ObsoleteCoroutinesApi"
    )
  }
}

This remain to be documented (see #859)

@pchmielowski
Copy link

@jcornaz Yes, this is also a nice solution, however the goal is not just to make the warning disappear, but to write a better software. And I believe that creating a wrapper around obsolete API and not letting this obsolete API leak into the application code is a better approach ;)

@jcornaz
Copy link
Contributor Author

jcornaz commented Mar 7, 2019

And I believe that creating a wrapper around obsolete API and not letting this obsolete API leak into the application code is a better approach ;)

I see your point, but don't agree.

For me it just introduce a "Middle Man" code smell, without providing much benefits. When the new API will be out, all the wrappers would instantly become obsolete too and they would need to be deleted as well. So you'r wrappers are known to become obsolete in the future and you basically hide an obsolete API behind another obsolete API...

So I understand your intentions, which are very good. But in my opinion it is counter productive, and actually increase the technical debt.

@JakeWharton
Copy link
Contributor

JakeWharton commented Mar 7, 2019 via email

@jcornaz
Copy link
Contributor Author

jcornaz commented Mar 7, 2019

@elizarov, Do you actually recommend that we create wrappers instead of calling experimental coroutine API directly?

@JakeWharton is that what you do? Do you wrap all experimental coroutine functions?

All of that sounds a bit strange to me because I think the wrapper is then as obsolete as the underling API. So it doesn't really prevent my code from using obsolete API, does it?

And if kotlinx.coroutines ships binary incompatible changes, we anyway need to recompile if we don't want the wrapper to fail.

I'd be glad to hear other opinions on the topic.

@JakeWharton
Copy link
Contributor

JakeWharton commented Mar 7, 2019 via email

@jcornaz
Copy link
Contributor Author

jcornaz commented Mar 7, 2019

I don't expose them in APIs, yes.

Ah... but me neither. If I provide an API which is backed by kotlinx.coroutines, it is an implementation detail and I, of course don't leak the fact that I use kotlinx.coroutines behind the hood. But my API is not simple wrappers it does something. And my implementation does call the kotlinx.coroutines directly.

EDIT: To be more explicit, @JakeWharton, do you use wrapper to hide experimental coroutines API from your implementation?

@JakeWharton
Copy link
Contributor

JakeWharton commented Mar 7, 2019 via email

@jcornaz
Copy link
Contributor Author

jcornaz commented Mar 7, 2019

Cool. I see we are on the same page then.

That seems fine. Is that all the original question was asking

Actually the initial question was already answered and closed for quite a while already. But this last bit was not completely off-topic, since the question was: "What is the recommended approach for @ObsoleteCoroutinesApi".

@joeferner
Copy link

I would really like some guidance on this. Should channels not be used until this is resolved?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants