Fix Medium severity performance findings (PERF-17 to PERF-21) (#325)

* Fix Medium severity performance findings (PERF-17 to PERF-21)

This commit addresses the following performance findings:
- PERF-17: Implemented a message queue in `HermesWsClient` using `ConcurrentLinkedQueue`. If the WebSocket is disconnected, messages are queued and flushed upon a successful connection (`onOpen`).
- PERF-18: Added exponential backoff to `safeApiCall` for 5xx and IO exceptions, reducing the load on a struggling server.
- PERF-19: Optimized Kanban task filtering by performing `groupBy` upfront inside a `remember` block and passing item keys to `LazyColumn`, avoiding O(C×T) calculation per recomposition.
- PERF-20: Updated `getLogs` API in `HermesApiService` to accept `lines` and `limit` query params to truncate logs early, avoiding potential JSON parsing OOMs with large log files.
- PERF-21: Optimized drawer entry generation in `Navigation.kt` by grouping navigation items inside a `remember` block.

Fixes #282

* Fix Medium severity performance findings (PERF-17 to PERF-21)

This commit addresses the following performance findings:
- PERF-17: Implemented a message queue in `HermesWsClient` using `ConcurrentLinkedQueue`. If the WebSocket is disconnected, messages are queued and flushed upon a successful connection (`onOpen`).
- PERF-18: Added exponential backoff to `safeApiCall` for 5xx and IO exceptions, reducing the load on a struggling server.
- PERF-19: Optimized Kanban task filtering by performing `groupBy` upfront inside a `remember` block and passing item keys to `LazyColumn`, avoiding O(C×T) calculation per recomposition.
- PERF-20: Updated `getLogs` API in `HermesApiService` to accept `lines` and `limit` query params to truncate logs early, avoiding potential JSON parsing OOMs with large log files.
- PERF-21: Optimized drawer entry generation in `Navigation.kt` by grouping navigation items inside a `remember` block.

Fixes #282

* Fix Medium severity performance findings (PERF-17 to PERF-21)

This commit addresses the following performance findings:
- PERF-17: Implemented a message queue in `HermesWsClient` using `ConcurrentLinkedQueue`. If the WebSocket is disconnected, messages are queued and flushed upon a successful connection (`onOpen`).
- PERF-18: Added exponential backoff to `safeApiCall` for 5xx and IO exceptions, reducing the load on a struggling server.
- PERF-19: Optimized Kanban task filtering by performing `groupBy` upfront inside a `remember` block and passing item keys to `LazyColumn`, avoiding O(C×T) calculation per recomposition.
- PERF-20: Updated `getLogs` API in `HermesApiService` to accept `lines` and `limit` query params to truncate logs early, avoiding potential JSON parsing OOMs with large log files.
- PERF-21: Optimized drawer entry generation in `Navigation.kt` by grouping navigation items inside a `remember` block.

Fixes #282

* fix: resolve ktlint formatting issues in KanbanScreen.kt and Navigation.kt

* fix: fix ktlint import ordering in HermesWsClient.kt

---------

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-06-23 22:23:26 +03:00
1 parent 42fcf2a14b
commit d616c56176
7 files changed
+71 -42

No files matched your search

@@ -72,6 +72,11 @@ fun KanbanScreen(
task.assignedTo?.contains(query, ignoreCase = true) == true
}
}
val tasksByColumn =
remember(filteredTasks) {
filteredTasks.groupBy { it.status.lowercase() }
}
var showAddTaskDialog by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
@@ -149,13 +154,13 @@ fun KanbanScreen(
contentPadding = PaddingValues(16.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
) {
items(state.columns, key = { it.name }) { column ->
items(state.columns.size, key = {
index ->
state.columns[index].name
}) { columnIndex ->
val column = state.columns[columnIndex]
val colName = column.name
val colTasks =
filteredTasks.filter {
it.status.equals(colName, ignoreCase = true)
}
val columnIndex = state.columns.indexOf(column)
val colTasks = tasksByColumn[colName.lowercase()] ?: emptyList()
val prevColumn = state.columns.getOrNull(columnIndex - 1)
val nextColumn = state.columns.getOrNull(columnIndex + 1)
@@ -23,7 +23,7 @@ class LogsViewModel : ViewModel(), ToastHost {
fun loadLogs() {
safeLaunchLoad(
apiCall = { safeApiCall { ApiClient.hermesApi.getLogs() } },
apiCall = { safeApiCall { ApiClient.hermesApi.getLogs(lines = 1000) } },
onStart = { _uiState.update { it.copy(isLoading = true, errorMessage = null) } },
onSuccess = { data ->
val body = data