tools: Fix missing cleanup
This commit is contained in:
+17
-8
@@ -7,10 +7,10 @@ import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.libbox.NetworkQualityProgress
|
||||
import io.nekohasekai.libbox.NetworkQualityResult
|
||||
import io.nekohasekai.libbox.NetworkQualityTestHandler
|
||||
import io.nekohasekai.libbox.NetworkQualityTestSession
|
||||
import io.nekohasekai.sfa.R
|
||||
import io.nekohasekai.sfa.compose.base.BaseViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -41,7 +41,7 @@ data class NetworkQualityState(
|
||||
|
||||
class NetworkQualityViewModel : BaseViewModel<NetworkQualityState, Nothing>() {
|
||||
private var standaloneTest: io.nekohasekai.libbox.NetworkQualityTest? = null
|
||||
private var grpcJob: Job? = null
|
||||
private var nqSession: NetworkQualityTestSession? = null
|
||||
|
||||
override fun createInitialState() = NetworkQualityState()
|
||||
|
||||
@@ -114,8 +114,9 @@ class NetworkQualityViewModel : BaseViewModel<NetworkQualityState, Nothing>() {
|
||||
val handler = createHandler()
|
||||
|
||||
if (vpnRunning) {
|
||||
grpcJob = viewModelScope.launch(Dispatchers.IO) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
nqSession =
|
||||
Libbox.newStandaloneCommandClient()
|
||||
.startNetworkQualityTest(
|
||||
configURL,
|
||||
@@ -129,7 +130,7 @@ class NetworkQualityViewModel : BaseViewModel<NetworkQualityState, Nothing>() {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (!currentState.isRunning) return@withContext
|
||||
updateState { copy(isRunning = false) }
|
||||
grpcJob = null
|
||||
nqSession = null
|
||||
sendError(e)
|
||||
}
|
||||
}
|
||||
@@ -146,13 +147,21 @@ class NetworkQualityViewModel : BaseViewModel<NetworkQualityState, Nothing>() {
|
||||
}
|
||||
|
||||
fun cancelTest() {
|
||||
grpcJob?.cancel()
|
||||
grpcJob = null
|
||||
try {
|
||||
nqSession?.close()
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
nqSession = null
|
||||
standaloneTest?.cancel()
|
||||
standaloneTest = null
|
||||
updateState { copy(isRunning = false) }
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
cancelTest()
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun createHandler(): NetworkQualityTestHandler {
|
||||
return object : NetworkQualityTestHandler {
|
||||
override fun onProgress(progress: NetworkQualityProgress?) {
|
||||
@@ -196,7 +205,7 @@ class NetworkQualityViewModel : BaseViewModel<NetworkQualityState, Nothing>() {
|
||||
)
|
||||
}
|
||||
standaloneTest = null
|
||||
grpcJob = null
|
||||
nqSession = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +214,7 @@ class NetworkQualityViewModel : BaseViewModel<NetworkQualityState, Nothing>() {
|
||||
if (!currentState.isRunning) return@launch
|
||||
updateState { copy(isRunning = false) }
|
||||
standaloneTest = null
|
||||
grpcJob = null
|
||||
nqSession = null
|
||||
if (message != null) {
|
||||
sendErrorMessage(message)
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.libbox.STUNTestHandler
|
||||
import io.nekohasekai.libbox.STUNTestProgress
|
||||
import io.nekohasekai.libbox.STUNTestResult
|
||||
import io.nekohasekai.libbox.STUNTestSession
|
||||
import io.nekohasekai.sfa.compose.base.BaseViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -25,7 +25,7 @@ data class STUNTestState(
|
||||
|
||||
class STUNTestViewModel : BaseViewModel<STUNTestState, Nothing>() {
|
||||
private var standaloneTest: io.nekohasekai.libbox.STUNTest? = null
|
||||
private var grpcJob: Job? = null
|
||||
private var stunSession: STUNTestSession? = null
|
||||
|
||||
override fun createInitialState() = STUNTestState()
|
||||
|
||||
@@ -60,15 +60,16 @@ class STUNTestViewModel : BaseViewModel<STUNTestState, Nothing>() {
|
||||
val handler = createHandler()
|
||||
|
||||
if (vpnRunning) {
|
||||
grpcJob = viewModelScope.launch(Dispatchers.IO) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
stunSession =
|
||||
Libbox.newStandaloneCommandClient()
|
||||
.startSTUNTest(server, outboundTag, handler)
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (!currentState.isRunning) return@withContext
|
||||
updateState { copy(isRunning = false) }
|
||||
grpcJob = null
|
||||
stunSession = null
|
||||
sendError(e)
|
||||
}
|
||||
}
|
||||
@@ -85,13 +86,21 @@ class STUNTestViewModel : BaseViewModel<STUNTestState, Nothing>() {
|
||||
}
|
||||
|
||||
fun cancelTest() {
|
||||
grpcJob?.cancel()
|
||||
grpcJob = null
|
||||
try {
|
||||
stunSession?.close()
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
stunSession = null
|
||||
standaloneTest?.cancel()
|
||||
standaloneTest = null
|
||||
updateState { copy(isRunning = false) }
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
cancelTest()
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun createHandler(): STUNTestHandler {
|
||||
return object : STUNTestHandler {
|
||||
override fun onProgress(progress: STUNTestProgress?) {
|
||||
@@ -126,7 +135,7 @@ class STUNTestViewModel : BaseViewModel<STUNTestState, Nothing>() {
|
||||
)
|
||||
}
|
||||
standaloneTest = null
|
||||
grpcJob = null
|
||||
stunSession = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +144,7 @@ class STUNTestViewModel : BaseViewModel<STUNTestState, Nothing>() {
|
||||
if (!currentState.isRunning) return@launch
|
||||
updateState { copy(isRunning = false) }
|
||||
standaloneTest = null
|
||||
grpcJob = null
|
||||
stunSession = null
|
||||
if (message != null) {
|
||||
sendErrorMessage(message)
|
||||
}
|
||||
|
||||
+10
-17
@@ -1,13 +1,12 @@
|
||||
package io.nekohasekai.sfa.compose.screen.tools
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import io.nekohasekai.libbox.CommandClient
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.libbox.TailscalePingHandler
|
||||
import io.nekohasekai.libbox.TailscalePingResult
|
||||
import io.nekohasekai.libbox.TailscalePingSession
|
||||
import io.nekohasekai.sfa.compose.base.BaseViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -23,8 +22,7 @@ data class TailscalePingState(
|
||||
|
||||
class TailscalePingViewModel : BaseViewModel<TailscalePingState, Nothing>() {
|
||||
private val maxHistorySize = 30
|
||||
private var commandClient: CommandClient? = null
|
||||
private var grpcJob: Job? = null
|
||||
private var pingSession: TailscalePingSession? = null
|
||||
|
||||
override fun createInitialState() = TailscalePingState()
|
||||
|
||||
@@ -37,12 +35,11 @@ class TailscalePingViewModel : BaseViewModel<TailscalePingState, Nothing>() {
|
||||
)
|
||||
}
|
||||
|
||||
val client = Libbox.newStandaloneCommandClient()
|
||||
commandClient = client
|
||||
|
||||
grpcJob = viewModelScope.launch(Dispatchers.IO) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
client.startTailscalePing(
|
||||
pingSession =
|
||||
Libbox.newStandaloneCommandClient()
|
||||
.startTailscalePing(
|
||||
endpointTag,
|
||||
peerIP,
|
||||
object : TailscalePingHandler {
|
||||
@@ -73,8 +70,7 @@ class TailscalePingViewModel : BaseViewModel<TailscalePingState, Nothing>() {
|
||||
viewModelScope.launch {
|
||||
if (!currentState.isRunning) return@launch
|
||||
updateState { copy(isRunning = false) }
|
||||
commandClient = null
|
||||
grpcJob = null
|
||||
pingSession = null
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -83,21 +79,18 @@ class TailscalePingViewModel : BaseViewModel<TailscalePingState, Nothing>() {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (!currentState.isRunning) return@withContext
|
||||
updateState { copy(isRunning = false) }
|
||||
commandClient = null
|
||||
grpcJob = null
|
||||
pingSession = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stopPing() {
|
||||
grpcJob?.cancel()
|
||||
grpcJob = null
|
||||
try {
|
||||
commandClient?.disconnect()
|
||||
pingSession?.close()
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
commandClient = null
|
||||
pingSession = null
|
||||
updateState { copy(isRunning = false) }
|
||||
}
|
||||
|
||||
|
||||
+11
-7
@@ -3,10 +3,10 @@ package io.nekohasekai.sfa.compose.screen.tools
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.libbox.TailscaleStatusHandler
|
||||
import io.nekohasekai.libbox.TailscaleStatusSubscription
|
||||
import io.nekohasekai.libbox.TailscaleStatusUpdate
|
||||
import io.nekohasekai.sfa.compose.base.BaseViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
data class TailscalePeerData(
|
||||
@@ -63,7 +63,7 @@ data class TailscaleStatusState(
|
||||
)
|
||||
|
||||
class TailscaleStatusViewModel : BaseViewModel<TailscaleStatusState, Nothing>() {
|
||||
private var grpcJob: Job? = null
|
||||
private var statusSubscription: TailscaleStatusSubscription? = null
|
||||
|
||||
override fun createInitialState() = TailscaleStatusState()
|
||||
|
||||
@@ -71,8 +71,9 @@ class TailscaleStatusViewModel : BaseViewModel<TailscaleStatusState, Nothing>()
|
||||
if (currentState.isSubscribed) return
|
||||
updateState { copy(isSubscribed = true) }
|
||||
|
||||
grpcJob = viewModelScope.launch(Dispatchers.IO) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
statusSubscription =
|
||||
Libbox.newStandaloneCommandClient()
|
||||
.subscribeTailscaleStatus(object : TailscaleStatusHandler {
|
||||
override fun onStatusUpdate(status: TailscaleStatusUpdate) {
|
||||
@@ -87,7 +88,7 @@ class TailscaleStatusViewModel : BaseViewModel<TailscaleStatusState, Nothing>()
|
||||
viewModelScope.launch {
|
||||
if (!currentState.isSubscribed) return@launch
|
||||
updateState { copy(endpoints = emptyList(), isSubscribed = false) }
|
||||
grpcJob = null
|
||||
statusSubscription = null
|
||||
sendErrorMessage(message)
|
||||
}
|
||||
}
|
||||
@@ -95,15 +96,18 @@ class TailscaleStatusViewModel : BaseViewModel<TailscaleStatusState, Nothing>()
|
||||
} catch (_: Exception) {
|
||||
viewModelScope.launch {
|
||||
updateState { copy(endpoints = emptyList(), isSubscribed = false) }
|
||||
grpcJob = null
|
||||
statusSubscription = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun cancel() {
|
||||
grpcJob?.cancel()
|
||||
grpcJob = null
|
||||
try {
|
||||
statusSubscription?.close()
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
statusSubscription = null
|
||||
updateState { copy(endpoints = emptyList(), isSubscribed = false) }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user