FeedsRepository: better handling of exception and structured concurrency
The refresh() method launch too async child coroutines. When one was failing
its exception was caught so the coroutine scope and the other child coroutines
were not cancelled. Then the second child could fail but this time its
exception were not caught. This leads to a crash
--- a/app/src/main/java/com/geekorum/ttrss/articles_list/FeedsRepository.kt Fri Feb 15 11:08:52 2019 -0800
+++ b/app/src/main/java/com/geekorum/ttrss/articles_list/FeedsRepository.kt Sun Feb 17 21:10:48 2019 -0800
@@ -20,7 +20,6 @@
*/
package com.geekorum.ttrss.articles_list
-import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
@@ -32,7 +31,9 @@
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
+import timber.log.Timber
import javax.inject.Inject
/**
@@ -44,8 +45,6 @@
private val feedsDao: FeedsDao,
private val apiService: ApiService
) {
- private val TAG = FeedsRepository::class.java.simpleName
-
val allUnreadFeeds: LiveData<List<Feed>>
get() {
refresh()
@@ -102,11 +101,13 @@
private fun refresh() = GlobalScope.launch(Dispatchers.IO) {
try {
- val feeds = async { apiService.getFeeds() }
- val categories = async { apiService.getCategories() }
- feedsDao.setFeedsAndCategories(feeds.await(), categories.await())
+ coroutineScope {
+ val feeds = async { apiService.getFeeds() }
+ val categories = async { apiService.getCategories() }
+ feedsDao.setFeedsAndCategories(feeds.await(), categories.await())
+ }
} catch (e: ApiCallException) {
- Log.w(TAG, "Unable to refresh feeds and categories", e)
+ Timber.w(e, "Unable to refresh feeds and categories")
}
}
}