From 5a1c12f67554e5e39769947a576b7e1428fc261e Mon Sep 17 00:00:00 2001 From: Matthias Urhahn <matthias.urhahn@sap.com> Date: Wed, 25 Nov 2020 14:14:26 +0100 Subject: [PATCH] Improve TaskController logging and limit state history (DEV) (#1717) * Improve TaskController.kt logging * Cap TaskController's state history to 50 entries. * Determine oldest tasks to prune based on `finishedAt` instead of `startedAt` Co-authored-by: Kolya Opahle <k.opahle@sap.com> --- .../rki/coronawarnapp/task/TaskController.kt | 22 +++++++--- .../coronawarnapp/task/TaskControllerTest.kt | 40 +++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt index 932fb9beb..b7cc4ca6e 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/task/TaskController.kt @@ -123,7 +123,6 @@ class TaskController @Inject constructor( private suspend fun processMap() = internalTaskData.updateSafely { Timber.tag(TAG).d("Processing task data (count=%d)", size) - Timber.tag(TAG).v("Tasks before processing: %s", this.values) // Procress all unprocessed finished tasks procressFinishedTasks(this).let { @@ -137,7 +136,19 @@ class TaskController @Inject constructor( this.putAll(it) } - Timber.tag(TAG).v("Tasks after processing: %s", this.values) + if (size > TASK_HISTORY_LIMIT) { + Timber.v("Enforcing history limits (%d), need to remove %d.", TASK_HISTORY_LIMIT, size - TASK_HISTORY_LIMIT) + values + .filter { it.isFinished } + .sortedBy { it.finishedAt } + .take(size - TASK_HISTORY_LIMIT) + .forEach { + Timber.v("Removing from history: %s", get(it.id)) + remove(it.id) + } + } + + Timber.tag(TAG).v("Tasks after processing (count=%d):\n%s", size, values.joinToString("\n")) } private fun procressFinishedTasks(data: Map<UUID, InternalTaskState>): Map<UUID, InternalTaskState> { @@ -178,9 +189,9 @@ class TaskController @Inject constructor( it.id != state.id } Timber.tag(TAG).d("Task has %d siblings", siblingTasks.size) - Timber.tag(TAG).v( - "Sibling are:\n%s", siblingTasks.joinToString("\n") - ) + if (siblingTasks.isNotEmpty()) { + Timber.tag(TAG).v("Sibling are:\n%s", siblingTasks.joinToString("\n")) + } // Handle collision behavior for tasks of same type when { @@ -237,5 +248,6 @@ class TaskController @Inject constructor( companion object { private const val TAG = "TaskController" + private const val TASK_HISTORY_LIMIT = 50 } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/TaskControllerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/TaskControllerTest.kt index 581eab4dc..d84078cf9 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/TaskControllerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/task/TaskControllerTest.kt @@ -539,4 +539,44 @@ class TaskControllerTest : BaseIOTest() { instance.close() } + + @Test + fun `old tasks are pruned from history`() = runBlockingTest { + val instance = createInstance(scope = this) + + val expectedFiles = mutableListOf<File>() + + repeat(100) { + val arguments = QueueingTask.Arguments( + delay = 5, + values = listOf("TestText"), + path = File(testDir, UUID.randomUUID().toString()) + ) + expectedFiles.add(arguments.path) + + val request = DefaultTaskRequest(type = QueueingTask::class, arguments = arguments) + instance.submit(request) + delay(5) + } + + this.advanceUntilIdle() + + expectedFiles.forEach { + it.exists() shouldBe true + } + + val taskHistory = instance.tasks.first() + taskHistory.size shouldBe 50 + expectedFiles.size shouldBe 100 + + val sortedHistory = taskHistory.sortedBy { it.taskState.startedAt }.apply { + first().taskState.startedAt!!.isBefore(last().taskState.startedAt) shouldBe true + } + + expectedFiles.subList(50, 100) shouldBe sortedHistory.map { + (it.taskState.request.arguments as QueueingTask.Arguments).path + } + + instance.close() + } } -- GitLab