question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Easy Unsubscription

See original GitHub issue

One 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:closed
  • Created 6 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

7reactions
JakeWhartoncommented, Mar 12, 2018

Pass a parent Job, cancel the parent.

Closeable is JVM-specific.

4reactions
jcornazcommented, Mar 11, 2018

In your latest code example, if you cancel the job returned by launch, it would make the receive method performed by consumeEach to throw a cancellation exception. And, because consumeEach use consume, 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 of consumeEach as you were expecting. and it is called Job not Disposable.

Aggregating the cancellation can easily be made with cancellation via explicit job.

For example:

val compositeDisposable = Job()

launch(parent = compositeDisposable) {
   channel.consumeEach { println(it) }
}

compositeDisposable.cancel() // This cancel all child jobs.
Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found