Refactor FailureCounter
This commit is contained in:
parent
08cd3d2f88
commit
fa2d699b1e
@ -19,7 +19,7 @@ import org.unifiedpush.distributor.nextpush.account.AccountFactory
|
|||||||
import org.unifiedpush.distributor.nextpush.distributor.Distributor
|
import org.unifiedpush.distributor.nextpush.distributor.Distributor
|
||||||
import org.unifiedpush.distributor.nextpush.distributor.Distributor.deleteApp
|
import org.unifiedpush.distributor.nextpush.distributor.Distributor.deleteApp
|
||||||
import org.unifiedpush.distributor.nextpush.distributor.Distributor.deleteDevice
|
import org.unifiedpush.distributor.nextpush.distributor.Distributor.deleteDevice
|
||||||
import org.unifiedpush.distributor.nextpush.services.FailureHandler
|
import org.unifiedpush.distributor.nextpush.services.FailureCounter
|
||||||
import org.unifiedpush.distributor.nextpush.services.RestartWorker
|
import org.unifiedpush.distributor.nextpush.services.RestartWorker
|
||||||
import org.unifiedpush.distributor.nextpush.services.StartService
|
import org.unifiedpush.distributor.nextpush.services.StartService
|
||||||
import org.unifiedpush.distributor.nextpush.utils.TAG
|
import org.unifiedpush.distributor.nextpush.utils.TAG
|
||||||
@ -64,7 +64,7 @@ class AppAction(private val type: Type, private val argv: Map<String, Any>? = nu
|
|||||||
|
|
||||||
private fun restartService(context: Context) {
|
private fun restartService(context: Context) {
|
||||||
Log.d(TAG, "Restarting the Listener")
|
Log.d(TAG, "Restarting the Listener")
|
||||||
FailureHandler.clearFails()
|
FailureCounter.clearFails()
|
||||||
StartService.stopService {
|
StartService.stopService {
|
||||||
RestartWorker.run(context, delay = 0)
|
RestartWorker.run(context, delay = 0)
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ class AppAction(private val type: Type, private val argv: Map<String, Any>? = nu
|
|||||||
private fun logout(context: Context) {
|
private fun logout(context: Context) {
|
||||||
deleteDevice(context) {
|
deleteDevice(context) {
|
||||||
StartService.stopService()
|
StartService.stopService()
|
||||||
FailureHandler.clearFails()
|
FailureCounter.clearFails()
|
||||||
}
|
}
|
||||||
AccountFactory.logout(context)
|
AccountFactory.logout(context)
|
||||||
AppStore(context).wipe()
|
AppStore(context).wipe()
|
||||||
|
@ -21,7 +21,7 @@ import org.unifiedpush.distributor.nextpush.WakeLock
|
|||||||
import org.unifiedpush.distributor.nextpush.api.response.SSEResponse
|
import org.unifiedpush.distributor.nextpush.api.response.SSEResponse
|
||||||
import org.unifiedpush.distributor.nextpush.distributor.Distributor.deleteAppFromSSE
|
import org.unifiedpush.distributor.nextpush.distributor.Distributor.deleteAppFromSSE
|
||||||
import org.unifiedpush.distributor.nextpush.distributor.Distributor.sendMessage
|
import org.unifiedpush.distributor.nextpush.distributor.Distributor.sendMessage
|
||||||
import org.unifiedpush.distributor.nextpush.services.FailureHandler
|
import org.unifiedpush.distributor.nextpush.services.FailureCounter
|
||||||
import org.unifiedpush.distributor.nextpush.services.RestartWorker
|
import org.unifiedpush.distributor.nextpush.services.RestartWorker
|
||||||
import org.unifiedpush.distributor.nextpush.services.StartService
|
import org.unifiedpush.distributor.nextpush.services.StartService
|
||||||
import org.unifiedpush.distributor.nextpush.utils.LowKeepAliveNotification
|
import org.unifiedpush.distributor.nextpush.utils.LowKeepAliveNotification
|
||||||
@ -37,7 +37,7 @@ class SSEListener(val context: Context) : EventSourceListener() {
|
|||||||
override var timeout: Long? = AppCompanion.keepalive.get().toLong() + TIMEOUT_TOLERANCE
|
override var timeout: Long? = AppCompanion.keepalive.get().toLong() + TIMEOUT_TOLERANCE
|
||||||
|
|
||||||
override fun onOpen(eventSource: EventSource, response: Response) {
|
override fun onOpen(eventSource: EventSource, response: Response) {
|
||||||
FailureHandler.newEventSource(context, eventSource)
|
FailureCounter.newEventSource(context, eventSource)
|
||||||
StartingTimer.scheduleNewTimer(context, eventSource)
|
StartingTimer.scheduleNewTimer(context, eventSource)
|
||||||
WakeLock.instance?.release()
|
WakeLock.instance?.release()
|
||||||
try {
|
try {
|
||||||
@ -62,7 +62,7 @@ class SSEListener(val context: Context) : EventSourceListener() {
|
|||||||
|
|
||||||
"ping" -> {
|
"ping" -> {
|
||||||
AppCompanion.pinged.set(true)
|
AppCompanion.pinged.set(true)
|
||||||
FailureHandler.newPing(context)
|
FailureCounter.newPing(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
"keepalive" -> {
|
"keepalive" -> {
|
||||||
@ -107,7 +107,7 @@ class SSEListener(val context: Context) : EventSourceListener() {
|
|||||||
eventSource.cancel()
|
eventSource.cancel()
|
||||||
WakeLock.instance?.release()
|
WakeLock.instance?.release()
|
||||||
if (!shouldRestart()) return
|
if (!shouldRestart()) return
|
||||||
if (FailureHandler.newFail(context, eventSource)) {
|
if (FailureCounter.addFail(context, eventSource)) {
|
||||||
clearDebugVars()
|
clearDebugVars()
|
||||||
RestartWorker.run(context, delay = 0)
|
RestartWorker.run(context, delay = 0)
|
||||||
}
|
}
|
||||||
@ -131,9 +131,9 @@ class SSEListener(val context: Context) : EventSourceListener() {
|
|||||||
clearDebugVars()
|
clearDebugVars()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (FailureHandler.newFail(context, eventSource)) {
|
if (FailureCounter.addFail(context, eventSource)) {
|
||||||
clearDebugVars()
|
clearDebugVars()
|
||||||
val delay = when (FailureHandler.nFails()) {
|
val delay = when (FailureCounter.nFails) {
|
||||||
1 -> 2 // 2sec
|
1 -> 2 // 2sec
|
||||||
2 -> 5 // 5sec
|
2 -> 5 // 5sec
|
||||||
3 -> 20 // 20sec
|
3 -> 20 // 20sec
|
||||||
@ -186,7 +186,7 @@ class SSEListener(val context: Context) : EventSourceListener() {
|
|||||||
!AppCompanion.booting.getAndSet(false)
|
!AppCompanion.booting.getAndSet(false)
|
||||||
) {
|
) {
|
||||||
Timer().schedule(45_000L) { // 45 secs
|
Timer().schedule(45_000L) { // 45 secs
|
||||||
if (FailureHandler.newFail(context, eventSource)) {
|
if (FailureCounter.addFail(context, eventSource)) {
|
||||||
StartService.stopService()
|
StartService.stopService()
|
||||||
NoStartNotification(context).showSingle()
|
NoStartNotification(context).showSingle()
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import android.content.IntentFilter
|
|||||||
import android.os.BatteryManager
|
import android.os.BatteryManager
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import org.unifiedpush.distributor.nextpush.AppCompanion
|
import org.unifiedpush.distributor.nextpush.AppCompanion
|
||||||
import org.unifiedpush.distributor.nextpush.services.FailureHandler
|
import org.unifiedpush.distributor.nextpush.services.FailureCounter
|
||||||
import org.unifiedpush.distributor.nextpush.services.RestartWorker
|
import org.unifiedpush.distributor.nextpush.services.RestartWorker
|
||||||
import org.unifiedpush.distributor.nextpush.services.StartService
|
import org.unifiedpush.distributor.nextpush.services.StartService
|
||||||
import org.unifiedpush.distributor.nextpush.utils.TAG
|
import org.unifiedpush.distributor.nextpush.utils.TAG
|
||||||
@ -37,7 +37,7 @@ class BatteryCallback : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun restartServer(context: Context) {
|
private fun restartServer(context: Context) {
|
||||||
if (!FailureHandler.hasFailed()) {
|
if (FailureCounter.isRunningWithoutFailure) {
|
||||||
StartService.stopService {
|
StartService.stopService {
|
||||||
RestartWorker.run(context, delay = 0)
|
RestartWorker.run(context, delay = 0)
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import java.lang.Exception
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
import org.unifiedpush.distributor.nextpush.AppCompanion
|
import org.unifiedpush.distributor.nextpush.AppCompanion
|
||||||
import org.unifiedpush.distributor.nextpush.services.FailureHandler
|
import org.unifiedpush.distributor.nextpush.services.FailureCounter
|
||||||
import org.unifiedpush.distributor.nextpush.services.RegistrationCountCache
|
import org.unifiedpush.distributor.nextpush.services.RegistrationCountCache
|
||||||
import org.unifiedpush.distributor.nextpush.services.RestartWorker
|
import org.unifiedpush.distributor.nextpush.services.RestartWorker
|
||||||
import org.unifiedpush.distributor.nextpush.utils.TAG
|
import org.unifiedpush.distributor.nextpush.utils.TAG
|
||||||
@ -49,7 +49,7 @@ class NetworkCallback(val context: Context) : ConnectivityManager.NetworkCallbac
|
|||||||
*/
|
*/
|
||||||
private fun noInternet() {
|
private fun noInternet() {
|
||||||
AppCompanion.hasInternet.set(false)
|
AppCompanion.hasInternet.set(false)
|
||||||
FailureHandler.once()
|
FailureCounter.setFailOnce()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +58,7 @@ class NetworkCallback(val context: Context) : ConnectivityManager.NetworkCallbac
|
|||||||
*/
|
*/
|
||||||
private fun backOnline() {
|
private fun backOnline() {
|
||||||
// We first check if there is a fail registered, else a worker will run in 2 seconds
|
// We first check if there is a fail registered, else a worker will run in 2 seconds
|
||||||
if (FailureHandler.hasFailed(orNeverStart = false) && RegistrationCountCache.oneOrMore(context)) {
|
if (FailureCounter.hasFailed && RegistrationCountCache.oneOrMore(context)) {
|
||||||
Log.d(TAG, "Restarting worker")
|
Log.d(TAG, "Restarting worker")
|
||||||
RestartWorker.run(context, delay = 0)
|
RestartWorker.run(context, delay = 0)
|
||||||
} // else, it retries in max 2sec
|
} // else, it retries in max 2sec
|
||||||
|
@ -10,40 +10,49 @@ import org.unifiedpush.distributor.nextpush.utils.DisconnectedNotification
|
|||||||
import org.unifiedpush.distributor.nextpush.utils.NoPingNotification
|
import org.unifiedpush.distributor.nextpush.utils.NoPingNotification
|
||||||
import org.unifiedpush.distributor.nextpush.utils.TAG
|
import org.unifiedpush.distributor.nextpush.utils.TAG
|
||||||
|
|
||||||
object FailureHandler {
|
object FailureCounter {
|
||||||
|
|
||||||
private val ttlFails = AtomicInteger(0)
|
private object Atomics {
|
||||||
private val nFails = AtomicInteger(0)
|
val ttlFails = AtomicInteger(0)
|
||||||
private val nFailsBeforePing = AtomicInteger(0)
|
val nFails = AtomicInteger(0)
|
||||||
|
val nFailsBeforePing = AtomicInteger(0)
|
||||||
|
|
||||||
// This is the last eventSource opened
|
// This is the last eventSource opened
|
||||||
private val eventSource: AtomicReference<EventSource?> = AtomicReference(null)
|
val eventSource: AtomicReference<EventSource?> = AtomicReference(null)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the [eventSource] the current one?
|
* Is the [eventSource] the current one?
|
||||||
* Any eventSource is considered as the current if none is saved.
|
* Any eventSource is considered as the current if none is saved.
|
||||||
*/
|
*/
|
||||||
private fun isCurrentEventSource(eventSource: EventSource?): Boolean {
|
private fun isCurrentEventSource(eventSource: EventSource?): Boolean {
|
||||||
return this.eventSource.get()?.let {
|
return Atomics.eventSource.get()?.let {
|
||||||
it == eventSource
|
it == eventSource
|
||||||
} ?: true
|
} ?: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a new event source is set, we cancel the previous one
|
||||||
|
* and set [Atomics.nFails] to 0 and remove [DisconnectedNotification]
|
||||||
|
*/
|
||||||
fun newEventSource(context: Context, eventSource: EventSource) {
|
fun newEventSource(context: Context, eventSource: EventSource) {
|
||||||
Log.d(TAG, "newEvent/Eventsource: $eventSource")
|
Log.d(TAG, "newEvent/Eventsource: $eventSource")
|
||||||
this.eventSource.getAndSet(eventSource)?.cancel()
|
Atomics.eventSource.getAndSet(eventSource)?.cancel()
|
||||||
nFails.set(0)
|
Atomics.nFails.set(0)
|
||||||
DisconnectedNotification(context).delete()
|
DisconnectedNotification(context).delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a new ping is recorded, we set [Atomics.nFailsBeforePing] to 0
|
||||||
|
* and remove [NoPingNotification]
|
||||||
|
*/
|
||||||
fun newPing(context: Context) {
|
fun newPing(context: Context) {
|
||||||
nFailsBeforePing.set(0)
|
Atomics.nFailsBeforePing.set(0)
|
||||||
NoPingNotification(context).delete()
|
NoPingNotification(context).delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun nFails(): Int {
|
val nFails: Int
|
||||||
return nFails.get()
|
get() = Atomics.nFails.get()
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the [eventSource] and increase the counter of failed events.
|
* Check the [eventSource] and increase the counter of failed events.
|
||||||
@ -58,23 +67,23 @@ object FailureHandler {
|
|||||||
*
|
*
|
||||||
* @return `true` if the fail is from the current eventSource
|
* @return `true` if the fail is from the current eventSource
|
||||||
*/
|
*/
|
||||||
fun newFail(context: Context, eventSource: EventSource): Boolean {
|
fun addFail(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
|
||||||
return if (isCurrentEventSource(eventSource)) {
|
return if (isCurrentEventSource(eventSource)) {
|
||||||
Log.d(TAG, "EventSource is known or null")
|
Log.d(TAG, "EventSource is known or null")
|
||||||
ttlFails.getAndIncrement()
|
Atomics.ttlFails.getAndIncrement()
|
||||||
if (nFails.incrementAndGet() == 2) {
|
if (Atomics.nFails.incrementAndGet() == 2) {
|
||||||
DisconnectedNotification(context).showSingle()
|
DisconnectedNotification(context).showSingle()
|
||||||
}
|
}
|
||||||
if (AppCompanion.started.get() && !AppCompanion.pinged.get()) {
|
if (AppCompanion.started.get() && !AppCompanion.pinged.get()) {
|
||||||
Log.d(TAG, "The service has started and it has never received a ping.")
|
Log.d(TAG, "The service has started and it has never received a ping.")
|
||||||
if (nFailsBeforePing.incrementAndGet() == 5) {
|
if (Atomics.nFailsBeforePing.incrementAndGet() == 5) {
|
||||||
NoPingNotification(context).showSingle()
|
NoPingNotification(context).showSingle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.eventSource.getAndSet(null)?.cancel()
|
Atomics.eventSource.getAndSet(null)?.cancel()
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "This is an old EventSource.")
|
Log.d(TAG, "This is an old EventSource.")
|
||||||
@ -88,37 +97,35 @@ object FailureHandler {
|
|||||||
*
|
*
|
||||||
* Used when there is no Internet access.
|
* Used when there is no Internet access.
|
||||||
*/
|
*/
|
||||||
fun once() {
|
fun setFailOnce() {
|
||||||
Log.d(TAG, "once/Eventsource: $eventSource")
|
Log.d(TAG, "setFailOnce")
|
||||||
nFails.set(1)
|
Atomics.nFails.set(1)
|
||||||
this.eventSource.getAndSet(null)?.cancel()
|
Atomics.eventSource.getAndSet(null)?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearFails() {
|
fun clearFails() {
|
||||||
ttlFails.set(0)
|
Atomics.ttlFails.set(0)
|
||||||
nFails.set(0)
|
Atomics.nFails.set(0)
|
||||||
nFailsBeforePing.set(0)
|
Atomics.nFailsBeforePing.set(0)
|
||||||
this.eventSource.getAndSet(null)?.cancel()
|
Atomics.eventSource.getAndSet(null)?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the service started and and has already failed once ?
|
* Is an eventSource recorded, and there isn't any failure ?
|
||||||
*
|
|
||||||
* If [orNeverStart] is true (default) we consider a non-started service as a failed service
|
|
||||||
*/
|
*/
|
||||||
fun hasFailed(orNeverStart: Boolean = true): Boolean {
|
val isRunningWithoutFailure: Boolean
|
||||||
// nFails > 0 to be sure it is not actually restarting
|
get() = Atomics.eventSource.get() != null && !hasFailed
|
||||||
return if (orNeverStart) {
|
|
||||||
eventSource.get() == null
|
/**
|
||||||
} else {
|
* Has the service failed at least once ?
|
||||||
false
|
*/
|
||||||
} || nFails.get() > 0
|
val hasFailed: Boolean
|
||||||
}
|
get() = nFails > 0
|
||||||
|
|
||||||
fun getDebugInfo(): String {
|
fun getDebugInfo(): String {
|
||||||
return "ttlFails: ${ttlFails.get()}\n" +
|
return "ttlFails: ${Atomics.ttlFails.get()}\n" +
|
||||||
"nFails: $nFails\n" +
|
"nFails: $nFails\n" +
|
||||||
"nFailsBeforePing: $nFailsBeforePing\n" +
|
"nFailsBeforePing: ${Atomics.nFailsBeforePing.get()}\n" +
|
||||||
"eventSource null: ${eventSource.get() == null}"
|
"eventSource null: ${Atomics.eventSource.get() == null}"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -38,12 +38,12 @@ class RestartWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params
|
|||||||
if (currentDate.after(restartDate)) {
|
if (currentDate.after(restartDate)) {
|
||||||
Log.d(TAG, "We should have received an event before ${restartDate.time}. Restarting")
|
Log.d(TAG, "We should have received an event before ${restartDate.time}. Restarting")
|
||||||
/**
|
/**
|
||||||
* If there is at least one failure, we do not update [FailureHandler]'s counter,
|
* If there is at least one failure, we do not update [FailureCounter]'s counter,
|
||||||
* it will be done by the next requests.
|
* it will be done by the next requests.
|
||||||
* Else we add one failure to be sure the service restarts.
|
* Else we add one failure to be sure the service restarts.
|
||||||
*/
|
*/
|
||||||
if (!FailureHandler.hasFailed()) {
|
if (FailureCounter.isRunningWithoutFailure) {
|
||||||
FailureHandler.once()
|
FailureCounter.setFailOnce()
|
||||||
}
|
}
|
||||||
StartService.startListener(applicationContext)
|
StartService.startListener(applicationContext)
|
||||||
// We consider this run as the first event
|
// We consider this run as the first event
|
||||||
|
@ -74,7 +74,7 @@ class StartService : Service() {
|
|||||||
private fun startService() {
|
private fun startService() {
|
||||||
// If the service is running and we don't have any fail
|
// If the service is running and we don't have any fail
|
||||||
// In case somehow startService is called when everything is fine
|
// In case somehow startService is called when everything is fine
|
||||||
if (isServiceStarted && !FailureHandler.hasFailed()) return
|
if (isServiceStarted && FailureCounter.isRunningWithoutFailure) return
|
||||||
getAccount(this) ?: run {
|
getAccount(this) ?: run {
|
||||||
Log.d(TAG, "No account found")
|
Log.d(TAG, "No account found")
|
||||||
return
|
return
|
||||||
@ -103,7 +103,7 @@ class StartService : Service() {
|
|||||||
fun startListener(context: Context) {
|
fun startListener(context: Context) {
|
||||||
val hasRegistration = RegistrationCountCache.oneOrMore(context)
|
val hasRegistration = RegistrationCountCache.oneOrMore(context)
|
||||||
if (isServiceStarted &&
|
if (isServiceStarted &&
|
||||||
!FailureHandler.hasFailed() &&
|
FailureCounter.isRunningWithoutFailure &&
|
||||||
// We return only if there is one or more registration
|
// We return only if there is one or more registration
|
||||||
// because if there is no registration, this is a request to stop the SSE
|
// because if there is no registration, this is a request to stop the SSE
|
||||||
hasRegistration
|
hasRegistration
|
||||||
@ -117,7 +117,7 @@ class StartService : Service() {
|
|||||||
}
|
}
|
||||||
Log.d(TAG, "Starting the Listener")
|
Log.d(TAG, "Starting the Listener")
|
||||||
Log.d(TAG, "Service is started: $isServiceStarted")
|
Log.d(TAG, "Service is started: $isServiceStarted")
|
||||||
Log.d(TAG, "nFails: ${FailureHandler.nFails()}")
|
Log.d(TAG, "nFails: ${FailureCounter.nFails}")
|
||||||
Log.d(TAG, "Has registration: $hasRegistration")
|
Log.d(TAG, "Has registration: $hasRegistration")
|
||||||
val serviceIntent = Intent(context, StartService::class.java)
|
val serviceIntent = Intent(context, StartService::class.java)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
@ -2,7 +2,7 @@ package org.unifiedpush.distributor.nextpush.utils
|
|||||||
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import org.unifiedpush.distributor.nextpush.AppCompanion
|
import org.unifiedpush.distributor.nextpush.AppCompanion
|
||||||
import org.unifiedpush.distributor.nextpush.services.FailureHandler
|
import org.unifiedpush.distributor.nextpush.services.FailureCounter
|
||||||
import org.unifiedpush.distributor.nextpush.services.StartService
|
import org.unifiedpush.distributor.nextpush.services.StartService
|
||||||
|
|
||||||
fun getDebugInfo(): String {
|
fun getDebugInfo(): String {
|
||||||
@ -14,5 +14,5 @@ fun getDebugInfo(): String {
|
|||||||
"Keepalive: ${AppCompanion.keepalive.get()}\n" +
|
"Keepalive: ${AppCompanion.keepalive.get()}\n" +
|
||||||
"SSE started: ${AppCompanion.started}\n" +
|
"SSE started: ${AppCompanion.started}\n" +
|
||||||
"SSE pinged: ${AppCompanion.pinged}\n" +
|
"SSE pinged: ${AppCompanion.pinged}\n" +
|
||||||
FailureHandler.getDebugInfo()
|
FailureCounter.getDebugInfo()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user