From 1547045165478d577cf8357e5fd5d46ad7ee1097 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 12 Jun 2019 14:49:39 +0200 Subject: [PATCH] Request can now be canceled properly: it should fix the issue with live chunk being deleted. --- .../android/internal/network/Request.kt | 41 ++++++++++++------- .../session/group/DefaultGetGroupDataTask.kt | 31 +++++++------- .../room/relation/SendRelationWorker.kt | 5 ++- .../session/room/send/RedactEventWorker.kt | 5 ++- .../session/room/send/SendEventWorker.kt | 5 ++- 5 files changed, 49 insertions(+), 38 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt index 139d62154c..bbd5859b21 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt @@ -28,34 +28,45 @@ import com.squareup.moshi.Moshi import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.failure.MatrixError import im.vector.matrix.android.internal.di.MoshiProvider +import kotlinx.coroutines.suspendCancellableCoroutine import okhttp3.ResponseBody import retrofit2.Call import timber.log.Timber import java.io.IOException +import kotlin.coroutines.resume -internal inline fun executeRequest(block: Request.() -> Unit) = Request().apply(block).execute() +internal suspend inline fun executeRequest(block: Request.() -> Unit) = Request().apply(block).execute() internal class Request { private val moshi: Moshi = MoshiProvider.providesMoshi() lateinit var apiCall: Call - fun execute(): Try { - return Try { - val response = apiCall.runAsync(IO.async()).fix().unsafeRunSync() - if (response.isSuccessful) { - response.body() ?: throw IllegalStateException("The request returned a null body") - } else { - throw manageFailure(response.errorBody(), response.code()) + suspend fun execute(): Try { + return suspendCancellableCoroutine { continuation -> + continuation.invokeOnCancellation { + Timber.v("Request is canceled") + apiCall.cancel() } - }.recoverWith { - when (it) { - is IOException -> Failure.NetworkConnection(it) - is Failure.ServerError, - is Failure.OtherServerError -> it - else -> Failure.Unknown(it) - }.failure() + val result = Try { + val response = apiCall.runAsync(IO.async()).fix().unsafeRunSync() + if (response.isSuccessful) { + response.body() + ?: throw IllegalStateException("The request returned a null body") + } else { + throw manageFailure(response.errorBody(), response.code()) + } + }.recoverWith { + when (it) { + is IOException -> Failure.NetworkConnection(it) + is Failure.ServerError, + is Failure.OtherServerError -> it + else -> Failure.Unknown(it) + }.failure() + } + continuation.resume(result) } + } private fun manageFailure(errorBody: ResponseBody?, httpCode: Int): Throwable { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/DefaultGetGroupDataTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/DefaultGetGroupDataTask.kt index 0785c33472..3d547c5342 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/DefaultGetGroupDataTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/DefaultGetGroupDataTask.kt @@ -21,13 +21,13 @@ import arrow.core.fix import arrow.instances.`try`.monad.monad import arrow.typeclasses.binding import com.zhuinden.monarchy.Monarchy -import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.database.model.GroupSummaryEntity import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.group.model.GroupRooms import im.vector.matrix.android.internal.session.group.model.GroupSummaryResponse import im.vector.matrix.android.internal.session.group.model.GroupUsers +import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.util.tryTransactionSync import io.realm.kotlin.createObject @@ -45,21 +45,17 @@ internal class DefaultGetGroupDataTask( override suspend fun execute(params: GetGroupDataTask.Params): Try { val groupId = params.groupId + val groupSummary = executeRequest { + apiCall = groupAPI.getSummary(groupId) + } + val groupRooms = executeRequest { + apiCall = groupAPI.getRooms(groupId) + } + val groupUsers = executeRequest { + apiCall = groupAPI.getUsers(groupId) + } return Try.monad().binding { - - val groupSummary = executeRequest { - apiCall = groupAPI.getSummary(groupId) - }.bind() - - val groupRooms = executeRequest { - apiCall = groupAPI.getRooms(groupId) - }.bind() - - val groupUsers = executeRequest { - apiCall = groupAPI.getUsers(groupId) - }.bind() - - insertInDb(groupSummary, groupRooms, groupUsers, groupId).bind() + insertInDb(groupSummary.bind(), groupRooms.bind(), groupUsers.bind(), groupId).bind() }.fix() } @@ -71,12 +67,13 @@ internal class DefaultGetGroupDataTask( return monarchy .tryTransactionSync { realm -> val groupSummaryEntity = GroupSummaryEntity.where(realm, groupId).findFirst() - ?: realm.createObject(groupId) + ?: realm.createObject(groupId) groupSummaryEntity.avatarUrl = groupSummary.profile?.avatarUrl ?: "" val name = groupSummary.profile?.name groupSummaryEntity.displayName = if (name.isNullOrEmpty()) groupId else name - groupSummaryEntity.shortDescription = groupSummary.profile?.shortDescription ?: "" + groupSummaryEntity.shortDescription = groupSummary.profile?.shortDescription + ?: "" val roomIds = groupRooms.rooms.map { it.roomId } groupSummaryEntity.roomIds.clear() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt index 41184aaf14..824c85b8a4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt @@ -16,6 +16,7 @@ package im.vector.matrix.android.internal.session.room.relation import android.content.Context +import androidx.work.CoroutineWorker import androidx.work.Worker import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass @@ -32,7 +33,7 @@ import im.vector.matrix.android.internal.util.WorkerParamsFactory import org.koin.standalone.inject class SendRelationWorker(context: Context, params: WorkerParameters) - : Worker(context, params), MatrixKoinComponent { + : CoroutineWorker(context, params), MatrixKoinComponent { @JsonClass(generateAdapter = true) @@ -44,7 +45,7 @@ class SendRelationWorker(context: Context, params: WorkerParameters) private val roomAPI by inject() - override fun doWork(): Result { + override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) ?: return Result.failure() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt index 5056a93b08..e51889f4fb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt @@ -16,6 +16,7 @@ package im.vector.matrix.android.internal.session.room.send import android.content.Context +import androidx.work.CoroutineWorker import androidx.work.Worker import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass @@ -27,7 +28,7 @@ import im.vector.matrix.android.internal.util.WorkerParamsFactory import org.koin.standalone.inject internal class RedactEventWorker(context: Context, params: WorkerParameters) - : Worker(context, params), MatrixKoinComponent { + : CoroutineWorker(context, params), MatrixKoinComponent { @JsonClass(generateAdapter = true) internal data class Params( @@ -39,7 +40,7 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) private val roomAPI by inject() - override fun doWork(): Result { + override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) ?: return Result.failure() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt index 32239b53a8..3b2fd87b16 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt @@ -17,6 +17,7 @@ package im.vector.matrix.android.internal.session.room.send import android.content.Context +import androidx.work.CoroutineWorker import androidx.work.Worker import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass @@ -30,7 +31,7 @@ import im.vector.matrix.android.internal.util.WorkerParamsFactory import org.koin.standalone.inject internal class SendEventWorker(context: Context, params: WorkerParameters) - : Worker(context, params), MatrixKoinComponent { + : CoroutineWorker(context, params), MatrixKoinComponent { @JsonClass(generateAdapter = true) @@ -42,7 +43,7 @@ internal class SendEventWorker(context: Context, params: WorkerParameters) private val roomAPI by inject() private val localEchoUpdater by inject() - override fun doWork(): Result { + override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) ?: return Result.success()