Use coroutines in CaldavSynchronizer

pull/1051/head
Alex Baker 4 years ago
parent e2c897e43c
commit 5658fca41f

@ -12,7 +12,7 @@ import at.bitfire.dav4jvm.exception.UnauthorizedException
import at.bitfire.dav4jvm.property.*
import at.bitfire.dav4jvm.property.GetETag.Companion.fromResponse
import at.bitfire.ical4android.ICalendar.Companion.prodId
import com.todoroo.astrid.dao.TaskDaoBlocking
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.helper.UUIDHelper
import com.todoroo.astrid.service.TaskDeleter
@ -30,7 +30,7 @@ import org.tasks.billing.Inventory
import org.tasks.caldav.iCalendar.Companion.fromVtodo
import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavCalendar
import org.tasks.data.CaldavDaoBlocking
import org.tasks.data.CaldavDao
import org.tasks.data.CaldavTask
import org.tasks.time.DateTimeUtils
import timber.log.Timber
@ -46,8 +46,8 @@ import javax.net.ssl.SSLException
class CaldavSynchronizer @Inject constructor(
@param:ApplicationContext private val context: Context,
private val caldavDao: CaldavDaoBlocking,
private val taskDao: TaskDaoBlocking,
private val caldavDao: CaldavDao,
private val taskDao: TaskDao,
private val localBroadcastManager: LocalBroadcastManager,
private val taskDeleter: TaskDeleter,
private val inventory: Inventory,
@ -60,7 +60,7 @@ class CaldavSynchronizer @Inject constructor(
}
}
fun sync(account: CaldavAccount) {
suspend fun sync(account: CaldavAccount) {
if (!inventory.hasPro()) {
setError(account, context.getString(R.string.requires_pro_subscription))
return
@ -98,7 +98,7 @@ class CaldavSynchronizer @Inject constructor(
}
@Throws(IOException::class, DavException::class, KeyManagementException::class, NoSuchAlgorithmException::class)
private fun synchronize(account: CaldavAccount) {
private suspend fun synchronize(account: CaldavAccount) {
val caldavClient = client.forAccount(account)
val resources = caldavClient.calendars
val urls = resources.map { it.href.toString() }.toHashSet()
@ -131,7 +131,7 @@ class CaldavSynchronizer @Inject constructor(
setError(account, "")
}
private fun setError(account: CaldavAccount, message: String?) {
private suspend fun setError(account: CaldavAccount, message: String?) {
account.error = message
caldavDao.update(account)
localBroadcastManager.broadcastRefreshList()
@ -141,7 +141,7 @@ class CaldavSynchronizer @Inject constructor(
}
@Throws(DavException::class)
private fun sync(caldavCalendar: CaldavCalendar, resource: at.bitfire.dav4jvm.Response, httpClient: OkHttpClient) {
private suspend fun sync(caldavCalendar: CaldavCalendar, resource: at.bitfire.dav4jvm.Response, httpClient: OkHttpClient) {
Timber.d("sync(%s)", caldavCalendar)
val httpUrl = resource.href
pushLocalChanges(caldavCalendar, httpClient, httpUrl)
@ -210,7 +210,7 @@ class CaldavSynchronizer @Inject constructor(
localBroadcastManager.broadcastRefresh()
}
private fun pushLocalChanges(
private suspend fun pushLocalChanges(
caldavCalendar: CaldavCalendar, httpClient: OkHttpClient, httpUrl: HttpUrl) {
for (task in caldavDao.getDeleted(caldavCalendar.uuid!!)) {
deleteRemoteResource(httpClient, httpUrl, task)
@ -224,7 +224,7 @@ class CaldavSynchronizer @Inject constructor(
}
}
private fun deleteRemoteResource(
private suspend fun deleteRemoteResource(
httpClient: OkHttpClient, httpUrl: HttpUrl, caldavTask: CaldavTask): Boolean {
try {
if (!isNullOrEmpty(caldavTask.`object`)) {
@ -246,7 +246,7 @@ class CaldavSynchronizer @Inject constructor(
}
@Throws(IOException::class)
private fun pushTask(task: Task, httpClient: OkHttpClient, httpUrl: HttpUrl) {
private suspend fun pushTask(task: Task, httpClient: OkHttpClient, httpUrl: HttpUrl) {
Timber.d("pushing %s", task)
val caldavTask = caldavDao.getTask(task.id) ?: return
if (task.isDeleted) {

@ -4,12 +4,14 @@ import android.content.Context
import androidx.hilt.Assisted
import androidx.hilt.work.WorkerInject
import androidx.work.WorkerParameters
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import org.tasks.LocalBroadcastManager
import org.tasks.analytics.Firebase
import org.tasks.caldav.CaldavSynchronizer
import org.tasks.data.CaldavAccount.Companion.TYPE_LOCAL
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskListDao
import org.tasks.etesync.EteSynchronizer
@ -43,7 +45,7 @@ class SyncWork @WorkerInject constructor(
preferences.isSyncOngoing = true
localBroadcastManager.broadcastRefresh()
try {
sync()
caldavJobs().plus(googleTaskJobs()).forEach { it.await() }
} catch (e: Exception) {
firebase.reportException(e)
} finally {
@ -53,9 +55,9 @@ class SyncWork @WorkerInject constructor(
return Result.success()
}
@Throws(InterruptedException::class)
private suspend fun sync() = coroutineScope {
val deferredCaldav = caldavDao.getAccounts()
private suspend fun caldavJobs(): List<Deferred<Unit>> = coroutineScope {
caldavDao.getAccounts()
.filterNot { it.accountType == TYPE_LOCAL }
.map {
async(Dispatchers.IO) {
if (it.isCaldavAccount) {
@ -65,16 +67,16 @@ class SyncWork @WorkerInject constructor(
}
}
}
val deferredGoogleTasks = googleTaskListDao
}
private suspend fun googleTaskJobs(): List<Deferred<Unit>> = coroutineScope {
googleTaskListDao
.getAccounts()
.mapIndexed { i, account ->
async(Dispatchers.IO) {
googleTaskSynchronizer.sync(account, i)
}
}
deferredCaldav
.plus(deferredGoogleTasks)
.forEach { it.await() }
}
companion object {

Loading…
Cancel
Save