Restart only if the fail comes from current source

This commit is contained in:
sim 2023-08-31 08:10:30 +02:00
parent 5484ff6d59
commit 747beb7620
2 changed files with 34 additions and 23 deletions

View File

@ -101,9 +101,10 @@ class SSEListener(val context: Context) : EventSourceListener() {
Log.d(TAG, "onClosed: $eventSource") Log.d(TAG, "onClosed: $eventSource")
eventSource.cancel() eventSource.cancel()
if (!shouldRestart()) return if (!shouldRestart()) return
FailureHandler.newFail(context, eventSource) if (FailureHandler.newFail(context, eventSource)) {
clearVars() clearVars()
RestartWorker.run(context, delay = 0) RestartWorker.run(context, delay = 0)
}
} }
override fun onFailure(eventSource: EventSource, t: Throwable?, response: Response?) { override fun onFailure(eventSource: EventSource, t: Throwable?, response: Response?) {
@ -118,23 +119,25 @@ class SSEListener(val context: Context) : EventSourceListener() {
} }
if (!AppCompanion.hasInternet.get()) { if (!AppCompanion.hasInternet.get()) {
Log.d(TAG, "No Internet: do not restart") Log.d(TAG, "No Internet: do not restart")
FailureHandler.once(eventSource) if (FailureHandler.once(eventSource)) {
clearVars() clearVars()
}
return return
} }
FailureHandler.newFail(context, eventSource) if (FailureHandler.newFail(context, eventSource)) {
clearVars() clearVars()
val delay = when (FailureHandler.nFails()) { val delay = when (FailureHandler.nFails()) {
1 -> 2 // 2sec 1 -> 2 // 2sec
2 -> 5 // 5sec 2 -> 5 // 5sec
3 -> 20 // 20sec 3 -> 20 // 20sec
4 -> 60 // 1min 4 -> 60 // 1min
5 -> 300 // 5min 5 -> 300 // 5min
6 -> 600 // 10min 6 -> 600 // 10min
else -> return // else keep the worker with its 16min else -> return // else keep the worker with its 16min
}.toLong() }.toLong()
Log.d(TAG, "Retrying in $delay s") Log.d(TAG, "Retrying in $delay s")
RestartWorker.run(context, delay = delay) RestartWorker.run(context, delay = delay)
}
} }
private fun shouldRestart(): Boolean { private fun shouldRestart(): Boolean {

View File

@ -18,7 +18,7 @@ object FailureHandler {
// This is the last eventSource opened // This is the last eventSource opened
private val eventSource: AtomicReference<EventSource?> = AtomicReference(null) private val eventSource: AtomicReference<EventSource?> = AtomicReference(null)
private fun isRightEventSource(eventSource: EventSource?): Boolean { private fun isCurrentEventSource(eventSource: EventSource?): Boolean {
return this.eventSource.get()?.let { return this.eventSource.get()?.let {
it == eventSource it == eventSource
} ?: true } ?: true
@ -39,11 +39,12 @@ object FailureHandler {
return nFails.get() return nFails.get()
} }
fun newFail(context: Context, eventSource: EventSource?) { // Returns true if the fail is from the current eventSource
fun newFail(context: Context, eventSource: EventSource?): Boolean {
Log.d(TAG, "newFail/Eventsource: $eventSource") Log.d(TAG, "newFail/Eventsource: $eventSource")
// ignore fails from a possible old eventSource // ignore fails from a possible old eventSource
// if we are already reconnected // if we are already reconnected
if (isRightEventSource(eventSource)) { return if (isCurrentEventSource(eventSource)) {
Log.d(TAG, "EventSource is known or null") Log.d(TAG, "EventSource is known or null")
ttlFails.getAndIncrement() ttlFails.getAndIncrement()
if (nFails.incrementAndGet() == 2) { if (nFails.incrementAndGet() == 2) {
@ -56,21 +57,28 @@ object FailureHandler {
} }
} }
this.eventSource.getAndSet(null)?.cancel() this.eventSource.getAndSet(null)?.cancel()
true
} else { } else {
Log.d(TAG, "This is an old EventSource.")
eventSource?.cancel() eventSource?.cancel()
false
} }
} }
fun once(eventSource: EventSource?) { // Returns true if the fail is from the current eventSource
fun once(eventSource: EventSource?): Boolean {
Log.d(TAG, "once/Eventsource: $eventSource") Log.d(TAG, "once/Eventsource: $eventSource")
// ignore fails from a possible old eventSource // ignore fails from a possible old eventSource
// if we are already reconnected // if we are already reconnected
if (isRightEventSource(eventSource)) { return if (isCurrentEventSource(eventSource)) {
Log.d(TAG, "EventSource is known or null") Log.d(TAG, "EventSource is known or null")
nFails.set(1) nFails.set(1)
this.eventSource.getAndSet(null)?.cancel() this.eventSource.getAndSet(null)?.cancel()
true
} else { } else {
Log.d(TAG, "This is an old EventSource.")
eventSource?.cancel() eventSource?.cancel()
false
} }
} }