uber / AutoDispose

Automatic binding+disposal of RxJava streams.

Home Page:https://uber.github.io/AutoDispose/

Repository from Github https://github.comuber/AutoDisposeRepository from Github https://github.comuber/AutoDispose

Question: how to implement a custom LifecycleScopeProvider

ericntd opened this issue · comments

Library version: 1.1.0

I've read https://uber.github.io/AutoDispose/ and looked, looked at Javadoc and https://github.com/uber/AutoDispose/blob/455ec23037d6e1af234d5fda9cd571c490d1b306/autodispose/src/test/java/autodispose2/TestScopeProviderTest.java but it's still unclear
I hope someone can shed some light on how I can achieve my goal: dispose the disposables when a specific event happens (user logs out

I have this custom LifecycleScopeProvider

class AuthenticationScopeProvider : LifecycleScopeProvider<AuthenticationEvent> {
    private val relay: BehaviorRelay<AuthenticationEvent> = BehaviorRelay.createDefault(
        AuthenticationEvent.PRE_AUTHENTICATED
    )

    private val function : CorrespondingEventsFunction<AuthenticationEvent> by lazy {
        CorrespondingEventsFunction<AuthenticationEvent> { event ->
            when (event) {
                AuthenticationEvent.PRE_AUTHENTICATED,
                AuthenticationEvent.AUTHENTICATED -> AuthenticationEvent.LOGGED_OUT
                AuthenticationEvent.LOGGED_OUT -> throw LifecycleEndedException()
            }
        }
    }

    override fun lifecycle(): Observable<AuthenticationEvent> {
        return relay.hide()
    }

    override fun correspondingEvents(): CorrespondingEventsFunction<AuthenticationEvent> {
        return function
    }

    override fun peekLifecycle(): AuthenticationEvent? {
        return relay.value
    }

    /**
     * Call this when the user is authenticated with the CMB backend.
     */
    fun becomeAuthenticated() {
        if (relay.value != AuthenticationEvent.AUTHENTICATED) {
            relay.accept(AuthenticationEvent.AUTHENTICATED)
        }
    }

    /**
     * Call this when a logout has started.
     */
    fun becomeUnAuthenticated() {
        if (relay.value != AuthenticationEvent.LOGGED_OUT) {
            relay.accept(AuthenticationEvent.LOGGED_OUT)
        }
    }

But I'm not sure whether the disposal is actually happening
Both this test

    @Test
    fun `test dispose`() {
        val provider = AuthenticationScopeProvider()
    val obs = Single.fromCallable {
        Thread.sleep(2000L)
        return@fromCallable "something"
    }.subscribeOn(Schedulers.io())
    val proxy = obs
            .`as`(AutoDispose.autoDisposable(provider))

            val disposable = proxy.subscribe()
        provider.becomeUnAuthenticated();
    Assert.assertTrue(disposable.isDisposed)
    }

and this

@Test(expected = LifecycleEndedException::class)
    fun `test dispose`() {
        val provider = AuthenticationScopeProvider()
    val obs = Single.fromCallable {
        Thread.sleep(2000L)
        return@fromCallable "something"
    }.subscribeOn(Schedulers.io())
    val proxy = obs
            .`as`(AutoDispose.autoDisposable(provider))

            val disposable = proxy.subscribe()
        provider.becomeUnAuthenticated();
    }

fails

When I explicitly call provider.requestScope().subscribe(observer), the 2nd test passes

fun becomeUnAuthenticated() {
        if (relay.value != AuthenticationEvent.LOGGED_OUT) {
            relay.accept(AuthenticationEvent.LOGGED_OUT)
        }
        requestScope().subscribe(object : CompletableObserver {
            override fun onSubscribe(d: Disposable) {
                // no-op
            }

            override fun onComplete() {
                println("completed") // never triggered
            }

            override fun onError(e: Throwable) {
                e.printStackTrace()
            }
        })
    }

However, the onComplete() is never called for the observer
What am I missing?

Please use the discussions section for questions, this is the issue tracker