The first two parts of your requirements should be combined into one. You're asking for the chain to be triggered on NonCritical
and Critical
events, ergo the chain should not be triggered for Good
event. Likewise, you only need to trigger an event if the state is different from a previous event. For this two .filter
events should suffice:
var lastKnownState: State = null
publishSubject
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.filter(this::checkStateDiffers) // Check we have a new state
.filter { state -> state != State.Good } // Check event is good
.subscribe {
AppLogger.printLog("Trigger Success --> ")
}
...
private fun checkStateDiffers(val state: State): Boolean {
val isDifferent = state != lastKnownState
if (isDifferent) lastKnownState = state // Update known state if changed
return isDifferent
}
The timeout requirement is a bit trickier. RxJava's timeout()
operator gives the option of emitting an error when nothing new has been received for a period of time. However I am assuming that you want to keep listening for events even after you receive a timeout. Likewise, if we just send another Critical
event it'll be dropped by the first filter
. So in this case I'd recommend a second disposable that just has the job of listening for this timeout.
Disposable timeoutDisp = publishSubject
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.timeout(15, TimeUnit.SECONDS)
.onErrorResumeNext(State.Timeout)
.filter { state -> state == State.Timeout }
.filter { state -> lastKnownState == State.Critical }
.subscribe {
AppLogger.printLog("Timeout Success --> ")
}
Also adjust the checkStateDiffers()
to not save this Timeout
state in the first chain.
private fun checkStateDiffers(val state: State): Boolean {
if (state == State.Timeout) return true
var isDifferent = state != lastKnownState
if (isDifferent) lastKnownState = state // Update known state if changed
return isDifferent
}