Easy Unsubscription
See original GitHub issueOne of the best parts of Rx is that unsubscriptions automatically transfer upstream. I can create a complex stream from multiple data sources, transform them, and subscribe to them. Then, I can add them to a CompositeDisposable
- which can automatically get cleared during the appropriate lifecycle event, like onDestroyed()
(I’m an android developer). It would be really helpful if co-routines could implement this behavior.
val disposables = CompositeDisposable()
// writeable stream in our model layer
val writeableSource: Subject<Int> = PublishSubject.create()
// readable stream. our model layer only exposes readable properties
val readableSource: Observable<Int> = writeableSource
val disposable = readableSource.map {
println("map executed for: $it")
it
}
.subscribe { println(it) }
.addTo(disposables)
writeableSource.onNext(1)
disposables.clear()
// should be ignored, because we previously called clear()
writeableSource.onNext(2)
// outputs:
// map executed for: 1
// 1
The biggest roadblock to this is that because Channel<T>
subscriptions are hot, unsubscriptions do not automatically transfer upstream. Would #254 provide this? More specifically:
// writeable stream in our model layer
val broadcastChannel = BroadcastChannel<Int>(10)
// readable stream
val source: SubscriptionReceiveChannel<Int> = broadcastChannel.openSubscription()
launch {
source // closing this prevents downstream operators from emitting
.map { it + 1 }
.map { it + 2 }
.also { receiveChannel ->
// calling `.cancel(null)` on the `ReceiveChannel` returned by the previous
// `.map` operator above does not close the upstream channel. This can easily
// cause a memory leak
receiveChannel.cancel(null)
}
// ideally, `.consumeEach()` could somehow be modified to return a `Disposable` like
// interface that cancels all upstream emissions
.consumeEach { println(it) }
}
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (4 by maintainers)
Top Results From Across the Web
Unsubscribe from emails, instantly - Unroll.Me
Easily unsubscribe in one click from email subscriptions. Sign up today!
Read more >Leave Me Alone: Easily Unsubscribe From Unwanted Emails
Manage your email subscriptions in a single click. Discover how to unsubscribe from emails you don't want using Leave Me Alone. Try our...
Read more >How to Unsubscribe From Unwanted Email - PCMag
Luckily, there are easy ways to kill unwanted emails, and they never involved sending ... Gmail makes it easy to unsubscribe on the...
Read more >5 Best Unsubscribe Apps To Clean Up Email Inbox in 2022
Clean Email is the best app to unsubscribe from emails anywhere, and anytime. It offers a simple yet efficient way to declutter your...
Read more >3 tools that easily unsubscribe you from emails - PCWorld
Unlistr lets you keep or unsubscribe to email with the push of a button. Similar to Unroll.me, Unlistr finds all your email subscriptions...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Pass a parent Job, cancel the parent.
Closeable is JVM-specific.
In your latest code example, if you cancel the job returned by launch, it would make the
receive
method performed byconsumeEach
to throw a cancellation exception. And, becauseconsumeEach
useconsume
, any exception thrown (including the cancellation exception) would cancel the channel upstream. And because the upstream is a subscription, cancelling means “unsubscribing”.So your code does return a kind of “disposable”. It is returned by
launch
instead ofconsumeEach
as you were expecting. and it is calledJob
notDisposable
.Aggregating the cancellation can easily be made with cancellation via explicit job.
For example: