forked from GitHub-Mirror/riotX-android
Request can now be canceled properly: it should fix the issue with live chunk being deleted.
This commit is contained in:
parent
5b0cab3e8a
commit
1547045165
@ -28,34 +28,45 @@ import com.squareup.moshi.Moshi
|
|||||||
import im.vector.matrix.android.api.failure.Failure
|
import im.vector.matrix.android.api.failure.Failure
|
||||||
import im.vector.matrix.android.api.failure.MatrixError
|
import im.vector.matrix.android.api.failure.MatrixError
|
||||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||||
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
|
||||||
internal inline fun <DATA> executeRequest(block: Request<DATA>.() -> Unit) = Request<DATA>().apply(block).execute()
|
internal suspend inline fun <DATA> executeRequest(block: Request<DATA>.() -> Unit) = Request<DATA>().apply(block).execute()
|
||||||
|
|
||||||
internal class Request<DATA> {
|
internal class Request<DATA> {
|
||||||
|
|
||||||
private val moshi: Moshi = MoshiProvider.providesMoshi()
|
private val moshi: Moshi = MoshiProvider.providesMoshi()
|
||||||
lateinit var apiCall: Call<DATA>
|
lateinit var apiCall: Call<DATA>
|
||||||
|
|
||||||
fun execute(): Try<DATA> {
|
suspend fun execute(): Try<DATA> {
|
||||||
return Try {
|
return suspendCancellableCoroutine { continuation ->
|
||||||
val response = apiCall.runAsync(IO.async()).fix().unsafeRunSync()
|
continuation.invokeOnCancellation {
|
||||||
if (response.isSuccessful) {
|
Timber.v("Request is canceled")
|
||||||
response.body() ?: throw IllegalStateException("The request returned a null body")
|
apiCall.cancel()
|
||||||
} else {
|
|
||||||
throw manageFailure(response.errorBody(), response.code())
|
|
||||||
}
|
}
|
||||||
}.recoverWith {
|
val result = Try {
|
||||||
when (it) {
|
val response = apiCall.runAsync(IO.async()).fix().unsafeRunSync()
|
||||||
is IOException -> Failure.NetworkConnection(it)
|
if (response.isSuccessful) {
|
||||||
is Failure.ServerError,
|
response.body()
|
||||||
is Failure.OtherServerError -> it
|
?: throw IllegalStateException("The request returned a null body")
|
||||||
else -> Failure.Unknown(it)
|
} else {
|
||||||
}.failure()
|
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 {
|
private fun manageFailure(errorBody: ResponseBody?, httpCode: Int): Throwable {
|
||||||
|
@ -21,13 +21,13 @@ import arrow.core.fix
|
|||||||
import arrow.instances.`try`.monad.monad
|
import arrow.instances.`try`.monad.monad
|
||||||
import arrow.typeclasses.binding
|
import arrow.typeclasses.binding
|
||||||
import com.zhuinden.monarchy.Monarchy
|
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.model.GroupSummaryEntity
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
import im.vector.matrix.android.internal.network.executeRequest
|
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.GroupRooms
|
||||||
import im.vector.matrix.android.internal.session.group.model.GroupSummaryResponse
|
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.session.group.model.GroupUsers
|
||||||
|
import im.vector.matrix.android.internal.task.Task
|
||||||
import im.vector.matrix.android.internal.util.tryTransactionSync
|
import im.vector.matrix.android.internal.util.tryTransactionSync
|
||||||
import io.realm.kotlin.createObject
|
import io.realm.kotlin.createObject
|
||||||
|
|
||||||
@ -45,21 +45,17 @@ internal class DefaultGetGroupDataTask(
|
|||||||
|
|
||||||
override suspend fun execute(params: GetGroupDataTask.Params): Try<Unit> {
|
override suspend fun execute(params: GetGroupDataTask.Params): Try<Unit> {
|
||||||
val groupId = params.groupId
|
val groupId = params.groupId
|
||||||
|
val groupSummary = executeRequest<GroupSummaryResponse> {
|
||||||
|
apiCall = groupAPI.getSummary(groupId)
|
||||||
|
}
|
||||||
|
val groupRooms = executeRequest<GroupRooms> {
|
||||||
|
apiCall = groupAPI.getRooms(groupId)
|
||||||
|
}
|
||||||
|
val groupUsers = executeRequest<GroupUsers> {
|
||||||
|
apiCall = groupAPI.getUsers(groupId)
|
||||||
|
}
|
||||||
return Try.monad().binding {
|
return Try.monad().binding {
|
||||||
|
insertInDb(groupSummary.bind(), groupRooms.bind(), groupUsers.bind(), groupId).bind()
|
||||||
val groupSummary = executeRequest<GroupSummaryResponse> {
|
|
||||||
apiCall = groupAPI.getSummary(groupId)
|
|
||||||
}.bind()
|
|
||||||
|
|
||||||
val groupRooms = executeRequest<GroupRooms> {
|
|
||||||
apiCall = groupAPI.getRooms(groupId)
|
|
||||||
}.bind()
|
|
||||||
|
|
||||||
val groupUsers = executeRequest<GroupUsers> {
|
|
||||||
apiCall = groupAPI.getUsers(groupId)
|
|
||||||
}.bind()
|
|
||||||
|
|
||||||
insertInDb(groupSummary, groupRooms, groupUsers, groupId).bind()
|
|
||||||
}.fix()
|
}.fix()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,12 +67,13 @@ internal class DefaultGetGroupDataTask(
|
|||||||
return monarchy
|
return monarchy
|
||||||
.tryTransactionSync { realm ->
|
.tryTransactionSync { realm ->
|
||||||
val groupSummaryEntity = GroupSummaryEntity.where(realm, groupId).findFirst()
|
val groupSummaryEntity = GroupSummaryEntity.where(realm, groupId).findFirst()
|
||||||
?: realm.createObject(groupId)
|
?: realm.createObject(groupId)
|
||||||
|
|
||||||
groupSummaryEntity.avatarUrl = groupSummary.profile?.avatarUrl ?: ""
|
groupSummaryEntity.avatarUrl = groupSummary.profile?.avatarUrl ?: ""
|
||||||
val name = groupSummary.profile?.name
|
val name = groupSummary.profile?.name
|
||||||
groupSummaryEntity.displayName = if (name.isNullOrEmpty()) groupId else 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 }
|
val roomIds = groupRooms.rooms.map { it.roomId }
|
||||||
groupSummaryEntity.roomIds.clear()
|
groupSummaryEntity.roomIds.clear()
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package im.vector.matrix.android.internal.session.room.relation
|
package im.vector.matrix.android.internal.session.room.relation
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.work.CoroutineWorker
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
@ -32,7 +33,7 @@ import im.vector.matrix.android.internal.util.WorkerParamsFactory
|
|||||||
import org.koin.standalone.inject
|
import org.koin.standalone.inject
|
||||||
|
|
||||||
class SendRelationWorker(context: Context, params: WorkerParameters)
|
class SendRelationWorker(context: Context, params: WorkerParameters)
|
||||||
: Worker(context, params), MatrixKoinComponent {
|
: CoroutineWorker(context, params), MatrixKoinComponent {
|
||||||
|
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
@ -44,7 +45,7 @@ class SendRelationWorker(context: Context, params: WorkerParameters)
|
|||||||
|
|
||||||
private val roomAPI by inject<RoomAPI>()
|
private val roomAPI by inject<RoomAPI>()
|
||||||
|
|
||||||
override fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
||||||
?: return Result.failure()
|
?: return Result.failure()
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package im.vector.matrix.android.internal.session.room.send
|
package im.vector.matrix.android.internal.session.room.send
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.work.CoroutineWorker
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
@ -27,7 +28,7 @@ import im.vector.matrix.android.internal.util.WorkerParamsFactory
|
|||||||
import org.koin.standalone.inject
|
import org.koin.standalone.inject
|
||||||
|
|
||||||
internal class RedactEventWorker(context: Context, params: WorkerParameters)
|
internal class RedactEventWorker(context: Context, params: WorkerParameters)
|
||||||
: Worker(context, params), MatrixKoinComponent {
|
: CoroutineWorker(context, params), MatrixKoinComponent {
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class Params(
|
internal data class Params(
|
||||||
@ -39,7 +40,7 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters)
|
|||||||
|
|
||||||
private val roomAPI by inject<RoomAPI>()
|
private val roomAPI by inject<RoomAPI>()
|
||||||
|
|
||||||
override fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
||||||
?: return Result.failure()
|
?: return Result.failure()
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package im.vector.matrix.android.internal.session.room.send
|
package im.vector.matrix.android.internal.session.room.send
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.work.CoroutineWorker
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
@ -30,7 +31,7 @@ import im.vector.matrix.android.internal.util.WorkerParamsFactory
|
|||||||
import org.koin.standalone.inject
|
import org.koin.standalone.inject
|
||||||
|
|
||||||
internal class SendEventWorker(context: Context, params: WorkerParameters)
|
internal class SendEventWorker(context: Context, params: WorkerParameters)
|
||||||
: Worker(context, params), MatrixKoinComponent {
|
: CoroutineWorker(context, params), MatrixKoinComponent {
|
||||||
|
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
@ -42,7 +43,7 @@ internal class SendEventWorker(context: Context, params: WorkerParameters)
|
|||||||
private val roomAPI by inject<RoomAPI>()
|
private val roomAPI by inject<RoomAPI>()
|
||||||
private val localEchoUpdater by inject<LocalEchoUpdater>()
|
private val localEchoUpdater by inject<LocalEchoUpdater>()
|
||||||
|
|
||||||
override fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
|
|
||||||
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
||||||
?: return Result.success()
|
?: return Result.success()
|
||||||
|
Loading…
Reference in New Issue
Block a user