feat: optimize network stack (#404)

* feat: optimize network stack and connection management

Refactor OkHttp connection pools, consolidate Gson serialization, add network-aware WebSocket reconnects, and deduplicate concurrent requests.

* test: update mapping assertions for AuthExpired

* refactor: address PR review feedback on network stack

Simplify health check, improve authenticator cookie matching robustness, resolve nit imports, and add unit tests.
This commit is contained in:
M57 authored and GitHub committed 2026-06-27 00:45:48 +03:00
1 parent 9344c3bd6e
commit 85c4662537
19 files changed
+455 -206

No files matched your search

@@ -9,6 +9,7 @@ import com.m57.hermescontrol.data.remote.safeApiCall
import com.m57.hermescontrol.ui.common.ToastHost
import com.m57.hermescontrol.ui.common.safeLaunchLoad
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -23,26 +24,32 @@ data class CronJobsUiState(
val toastMessage: String? = null,
)
class CronJobsViewModel : ViewModel(), ToastHost {
class CronJobsViewModel :
ViewModel(),
ToastHost {
private val _uiState = MutableStateFlow(CronJobsUiState())
val uiState: StateFlow<CronJobsUiState> = _uiState.asStateFlow()
private var loadJob: Job? = null
fun loadCronJobs() {
safeLaunchLoad(
apiCall = { safeApiCall { ApiClient.hermesApi.getCronJobs() } },
onStart = { _uiState.update { it.copy(isLoading = true, errorMessage = null) } },
onSuccess = { data ->
_uiState.update { it.copy(isLoading = false, jobs = data.orEmpty()) }
},
onError = { errorMsg ->
_uiState.update {
it.copy(
isLoading = false,
errorMessage = "Failed to load cron jobs: $errorMsg",
)
}
},
)
loadJob =
safeLaunchLoad(
currentJob = loadJob,
apiCall = { safeApiCall { ApiClient.hermesApi.getCronJobs() } },
onStart = { _uiState.update { it.copy(isLoading = true, errorMessage = null) } },
onSuccess = { data ->
_uiState.update { it.copy(isLoading = false, jobs = data.orEmpty()) }
},
onError = { errorMsg ->
_uiState.update {
it.copy(
isLoading = false,
errorMessage = "Failed to load cron jobs: $errorMsg",
)
}
},
)
}
fun pauseCronJob(id: String) {