Merge pull request #626 from ultrasonic/cachecleaner

Migrate CacheCleaner to Coroutine
This commit is contained in:
Nite 2021-11-18 18:17:30 +01:00 committed by GitHub
commit 45e9728e0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 58 additions and 75 deletions

View File

@ -1,10 +1,13 @@
package org.moire.ultrasonic.util package org.moire.ultrasonic.util
import android.os.AsyncTask
import android.os.StatFs import android.os.StatFs
import java.io.File import java.io.File
import java.util.ArrayList import java.util.ArrayList
import java.util.HashSet import java.util.HashSet
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.java.KoinJavaComponent.inject import org.koin.java.KoinJavaComponent.inject
import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.domain.Playlist import org.moire.ultrasonic.domain.Playlist
@ -22,42 +25,34 @@ import timber.log.Timber
/** /**
* Responsible for cleaning up files from the offline download cache on the filesystem. * Responsible for cleaning up files from the offline download cache on the filesystem.
*/ */
class CacheCleaner { class CacheCleaner : CoroutineScope by CoroutineScope(Dispatchers.IO) {
private fun exceptionHandler(tag: String): CoroutineExceptionHandler {
return CoroutineExceptionHandler { _, exception ->
Timber.w(exception, "Exception in CacheCleaner.$tag")
}
}
fun clean() { fun clean() {
try { launch(exceptionHandler("clean")) {
BackgroundCleanup().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) backgroundCleanup()
} catch (all: Exception) {
// If an exception is thrown, assume we execute correctly the next time
Timber.w(all, "Exception in CacheCleaner.clean")
} }
} }
fun cleanSpace() { fun cleanSpace() {
try { launch(exceptionHandler("cleanSpace")) {
BackgroundSpaceCleanup().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) backgroundSpaceCleanup()
} catch (all: Exception) {
// If an exception is thrown, assume we execute correctly the next time
Timber.w(all, "Exception in CacheCleaner.cleanSpace")
} }
} }
fun cleanPlaylists(playlists: List<Playlist>) { fun cleanPlaylists(playlists: List<Playlist>) {
try { launch(exceptionHandler("cleanPlaylists")) {
BackgroundPlaylistsCleanup().executeOnExecutor( backgroundPlaylistsCleanup(playlists)
AsyncTask.THREAD_POOL_EXECUTOR,
playlists
)
} catch (all: Exception) {
// If an exception is thrown, assume we execute correctly the next time
Timber.w(all, "Exception in CacheCleaner.cleanPlaylists")
} }
} }
private class BackgroundCleanup : AsyncTask<Void?, Void?, Void?>() { private fun backgroundCleanup() {
override fun doInBackground(vararg params: Void?): Void? {
try { try {
Thread.currentThread().name = "BackgroundCleanup"
val files: MutableList<File> = ArrayList() val files: MutableList<File> = ArrayList()
val dirs: MutableList<File> = ArrayList() val dirs: MutableList<File> = ArrayList()
@ -70,42 +65,32 @@ class CacheCleaner {
} catch (all: RuntimeException) { } catch (all: RuntimeException) {
Timber.e(all, "Error in cache cleaning.") Timber.e(all, "Error in cache cleaning.")
} }
return null
}
} }
private class BackgroundSpaceCleanup : AsyncTask<Void?, Void?, Void?>() { private fun backgroundSpaceCleanup() {
override fun doInBackground(vararg params: Void?): Void? {
try { try {
Thread.currentThread().name = "BackgroundSpaceCleanup"
val files: MutableList<File> = ArrayList() val files: MutableList<File> = ArrayList()
val dirs: MutableList<File> = ArrayList() val dirs: MutableList<File> = ArrayList()
findCandidatesForDeletion(musicDirectory, files, dirs) findCandidatesForDeletion(musicDirectory, files, dirs)
val bytesToDelete = getMinimumDelete(files) val bytesToDelete = getMinimumDelete(files)
if (bytesToDelete <= 0L) return null if (bytesToDelete > 0L) {
sortByAscendingModificationTime(files) sortByAscendingModificationTime(files)
val filesToNotDelete = findFilesToNotDelete() val filesToNotDelete = findFilesToNotDelete()
deleteFiles(files, filesToNotDelete, bytesToDelete, false) deleteFiles(files, filesToNotDelete, bytesToDelete, false)
}
} catch (all: RuntimeException) { } catch (all: RuntimeException) {
Timber.e(all, "Error in cache cleaning.") Timber.e(all, "Error in cache cleaning.")
} }
return null
}
} }
private class BackgroundPlaylistsCleanup : AsyncTask<List<Playlist>, Void?, Void?>() { private fun backgroundPlaylistsCleanup(vararg params: List<Playlist>) {
override fun doInBackground(vararg params: List<Playlist>): Void? {
try { try {
val activeServerProvider = inject<ActiveServerProvider>( val activeServerProvider = inject<ActiveServerProvider>(
ActiveServerProvider::class.java ActiveServerProvider::class.java
) )
Thread.currentThread().name = "BackgroundPlaylistsCleanup"
val server = activeServerProvider.value.getActiveServer().name val server = activeServerProvider.value.getActiveServer().name
val playlistFiles = listFiles(getPlaylistDirectory(server)) val playlistFiles = listFiles(getPlaylistDirectory(server))
val playlists = params[0] val playlists = params[0]
@ -120,8 +105,6 @@ class CacheCleaner {
} catch (all: RuntimeException) { } catch (all: RuntimeException) {
Timber.e(all, "Error in playlist cache cleaning.") Timber.e(all, "Error in playlist cache cleaning.")
} }
return null
}
} }
companion object { companion object {