From d9e24558ecb39b832c41f046e49185c4cdc51df2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 17 Dec 2018 16:42:22 +0100 Subject: [PATCH] Makes task configurable to allow choosing threads --- .../room/timeline/TimelineHolderTest.kt | 2 +- .../im/vector/matrix/android/internal/Task.kt | 9 ---- .../matrix/android/internal/TaskExecutor.kt | 27 ------------ .../android/internal/di/MatrixModule.kt | 2 +- .../session/group/DefaultGetGroupDataTask.kt | 2 +- .../internal/session/room/DefaultRoom.kt | 5 ++- .../room/members/LoadRoomMembersTask.kt | 2 +- .../timeline/DefaultGetContextOfEventTask.kt | 2 +- .../room/timeline/DefaultPaginationTask.kt | 2 +- .../room/timeline/DefaultTimelineHolder.kt | 6 +-- .../session/room/timeline/GetEventTask.kt | 2 +- .../room/timeline/TimelineBoundaryCallback.kt | 25 +++++------ .../android/internal/session/sync/SyncTask.kt | 2 +- .../internal/session/sync/job/SyncThread.kt | 38 ++++++++++------- .../android/internal/task/ConfigurableTask.kt | 42 +++++++++++++++++++ .../matrix/android/internal/task/Task.kt | 10 +++++ .../android/internal/task/TaskExecutor.kt | 34 +++++++++++++++ .../android/internal/task/TaskThread.kt | 8 ++++ 18 files changed, 144 insertions(+), 76 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/Task.kt delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/TaskExecutor.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/ConfigurableTask.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/Task.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/TaskExecutor.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/TaskThread.kt diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt index eb68af98..fc8731ab 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt @@ -6,7 +6,7 @@ import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.InstrumentedTest import im.vector.matrix.android.LiveDataTestObserver import im.vector.matrix.android.api.thread.MainThreadExecutor -import im.vector.matrix.android.internal.TaskExecutor +import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineHolder import im.vector.matrix.android.internal.session.room.timeline.TimelineBoundaryCallback import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/Task.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/Task.kt deleted file mode 100644 index 84c457d7..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/Task.kt +++ /dev/null @@ -1,9 +0,0 @@ -package im.vector.matrix.android.internal - -import arrow.core.Try - -interface Task { - - fun execute(params: PARAMS): Try - -} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/TaskExecutor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/TaskExecutor.kt deleted file mode 100644 index e720a24c..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/TaskExecutor.kt +++ /dev/null @@ -1,27 +0,0 @@ -package im.vector.matrix.android.internal - -import im.vector.matrix.android.api.MatrixCallback -import im.vector.matrix.android.api.util.Cancelable -import im.vector.matrix.android.internal.util.CancelableCoroutine -import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import timber.log.Timber - -internal class TaskExecutor(private val coroutineDispatchers: MatrixCoroutineDispatchers) { - - fun executeTask(task: Task, - params: PARAMS, - callback: MatrixCallback): Cancelable { - val job = GlobalScope.launch(coroutineDispatchers.main) { - val resultOrFailure = withContext(coroutineDispatchers.io) { - Timber.v("Executing ${task.javaClass} on ${Thread.currentThread().name}") - task.execute(params) - } - resultOrFailure.fold({ callback.onFailure(it) }, { callback.onSuccess(it) }) - } - return CancelableCoroutine(job) - } - -} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt index b0c0634d..ab2b5d0f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt @@ -1,7 +1,7 @@ package im.vector.matrix.android.internal.di import im.vector.matrix.android.api.MatrixOptions -import im.vector.matrix.android.internal.TaskExecutor +import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.util.BackgroundDetectionObserver import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import kotlinx.coroutines.Dispatchers 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 d1954956..587ac948 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 @@ -5,7 +5,7 @@ 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 +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 diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt index c24eb4be..38027bad 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt @@ -14,7 +14,8 @@ import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.MyMembership import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.util.Cancelable -import im.vector.matrix.android.internal.TaskExecutor +import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.RoomEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntity @@ -59,7 +60,7 @@ internal data class DefaultRoom( } else { val token = syncTokenStore.getLastToken() val params = LoadRoomMembersTask.Params(roomId, token, Membership.LEAVE) - taskExecutor.executeTask(loadRoomMembersTask, params, object : MatrixCallback {}) + loadRoomMembersTask.configureWith(params).executeBy(taskExecutor) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/LoadRoomMembersTask.kt index 04ebaa19..aa0160bf 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/LoadRoomMembersTask.kt @@ -3,7 +3,7 @@ package im.vector.matrix.android.internal.session.room.members import arrow.core.Try import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.session.room.model.Membership -import im.vector.matrix.android.internal.Task +import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.database.helper.addStateEvents import im.vector.matrix.android.internal.database.model.RoomEntity import im.vector.matrix.android.internal.database.query.where diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultGetContextOfEventTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultGetContextOfEventTask.kt index c4fc4831..2eabe6f2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultGetContextOfEventTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultGetContextOfEventTask.kt @@ -1,7 +1,7 @@ package im.vector.matrix.android.internal.session.room.timeline import arrow.core.Try -import im.vector.matrix.android.internal.Task +import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.room.RoomAPI import im.vector.matrix.android.internal.util.FilterUtil diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultPaginationTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultPaginationTask.kt index 30f7a32e..5dfb3c3f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultPaginationTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultPaginationTask.kt @@ -2,7 +2,7 @@ package im.vector.matrix.android.internal.session.room.timeline import arrow.core.Try import arrow.core.failure -import im.vector.matrix.android.internal.Task +import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.room.RoomAPI import im.vector.matrix.android.internal.util.FilterUtil diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineHolder.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineHolder.kt index a78297c2..86c07a3b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineHolder.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineHolder.kt @@ -4,11 +4,11 @@ import android.arch.lifecycle.LiveData import android.arch.paging.LivePagedListBuilder import android.arch.paging.PagedList import com.zhuinden.monarchy.Monarchy -import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.events.interceptor.EnrichedEventInterceptor import im.vector.matrix.android.api.session.events.model.EnrichedEvent import im.vector.matrix.android.api.session.room.TimelineHolder -import im.vector.matrix.android.internal.TaskExecutor +import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.ChunkEntityFields import im.vector.matrix.android.internal.database.model.EventEntity @@ -78,7 +78,7 @@ internal class DefaultTimelineHolder(private val roomId: String, private fun fetchEventIfNeeded(eventId: String) { if (!isEventPersisted(eventId)) { val params = GetContextOfEventTask.Params(roomId, eventId) - taskExecutor.executeTask(contextOfEventTask, params, object : MatrixCallback {}) + contextOfEventTask.configureWith(params).executeBy(taskExecutor) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/GetEventTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/GetEventTask.kt index 596d5801..2c61ecae 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/GetEventTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/GetEventTask.kt @@ -2,7 +2,7 @@ package im.vector.matrix.android.internal.session.room.timeline import arrow.core.Try import im.vector.matrix.android.api.session.events.model.Event -import im.vector.matrix.android.internal.Task +import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.room.RoomAPI diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineBoundaryCallback.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineBoundaryCallback.kt index 623237a7..3c9cb1bb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineBoundaryCallback.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineBoundaryCallback.kt @@ -4,7 +4,8 @@ import android.arch.paging.PagedList import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.events.model.EnrichedEvent -import im.vector.matrix.android.internal.TaskExecutor +import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.database.model.ChunkEntity import im.vector.matrix.android.internal.database.query.findAllIncludingEvents import im.vector.matrix.android.internal.util.PagingRequestHelper @@ -51,17 +52,17 @@ internal class TimelineBoundaryCallback(private val roomId: String, direction = direction, limit = limit) - taskExecutor.executeTask(paginationTask, params, createCallback(requestCallback)) + paginationTask.configureWith(params) + .dispatchTo(object : MatrixCallback { + override fun onSuccess(data: TokenChunkEvent) { + requestCallback.recordSuccess() + } + + override fun onFailure(failure: Throwable) { + requestCallback.recordFailure(failure) + } + }) + .executeBy(taskExecutor) } - - private fun createCallback(pagingRequestCallback: PagingRequestHelper.Request.Callback) = object : MatrixCallback { - override fun onSuccess(data: TokenChunkEvent) { - pagingRequestCallback.recordSuccess() - } - - override fun onFailure(failure: Throwable) { - pagingRequestCallback.recordFailure(failure) - } - } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt index 533019d3..5d5d4b60 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt @@ -1,7 +1,7 @@ package im.vector.matrix.android.internal.session.sync import arrow.core.Try -import im.vector.matrix.android.internal.Task +import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.filter.FilterBody import im.vector.matrix.android.internal.session.sync.model.SyncResponse diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncThread.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncThread.kt index 0a523a13..e41109f3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncThread.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncThread.kt @@ -3,7 +3,9 @@ package im.vector.matrix.android.internal.session.sync.job import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.util.Cancelable -import im.vector.matrix.android.internal.TaskExecutor +import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.task.TaskThread +import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.network.NetworkConnectivityChecker import im.vector.matrix.android.internal.session.sync.SyncTask import im.vector.matrix.android.internal.session.sync.SyncTokenStore @@ -80,21 +82,27 @@ internal class SyncThread(private val syncTask: SyncTask, Timber.v("Execute sync request...") val latch = CountDownLatch(1) val params = SyncTask.Params(nextBatch) - cancelableTask = taskExecutor.executeTask(syncTask, params, object : MatrixCallback { - override fun onSuccess(data: SyncResponse) { - nextBatch = data.nextBatch - syncTokenStore.saveToken(nextBatch) - latch.countDown() - } + cancelableTask = syncTask.configureWith(params) + .callbackOn(TaskThread.CALLER) + .executeOn(TaskThread.CALLER) + .dispatchTo(object : MatrixCallback { + override fun onSuccess(data: SyncResponse) { + nextBatch = data.nextBatch + syncTokenStore.saveToken(nextBatch) + latch.countDown() + } + + override fun onFailure(failure: Throwable) { + if (failure !is Failure.NetworkConnection) { + // Wait 10s before retrying + sleep(RETRY_WAIT_TIME_MS) + } + latch.countDown() + } + + }) + .executeBy(taskExecutor) - override fun onFailure(failure: Throwable) { - if (failure !is Failure.NetworkConnection) { - // Wait 10s before retrying - sleep(RETRY_WAIT_TIME_MS) - } - latch.countDown() - } - }) latch.await() } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/ConfigurableTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/ConfigurableTask.kt new file mode 100644 index 00000000..e5cc7b33 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/ConfigurableTask.kt @@ -0,0 +1,42 @@ +package im.vector.matrix.android.internal.task + +import arrow.core.Try +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.util.Cancelable + +internal fun Task.configureWith(params: PARAMS): ConfigurableTask { + return ConfigurableTask(this, params) +} + +internal data class ConfigurableTask( + val task: Task, + val params: PARAMS, + val callbackThread: TaskThread = TaskThread.MAIN, + val executionThread: TaskThread = TaskThread.IO, + val callback: MatrixCallback = object : MatrixCallback {} +) : Task { + + + override fun execute(params: PARAMS): Try { + return task.execute(params) + } + + fun callbackOn(thread: TaskThread): ConfigurableTask { + return copy(callbackThread = thread) + } + + fun executeOn(thread: TaskThread): ConfigurableTask { + return copy(executionThread = thread) + } + + fun dispatchTo(matrixCallback: MatrixCallback): ConfigurableTask { + return copy(callback = matrixCallback) + } + + fun executeBy(taskExecutor: TaskExecutor): Cancelable { + return taskExecutor.execute(this) + } + +} + + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/Task.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/Task.kt new file mode 100644 index 00000000..cd428757 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/Task.kt @@ -0,0 +1,10 @@ +package im.vector.matrix.android.internal.task + +import arrow.core.Try + +internal interface Task { + + fun execute(params: PARAMS): Try + +} + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/TaskExecutor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/TaskExecutor.kt new file mode 100644 index 00000000..fce0cd79 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/TaskExecutor.kt @@ -0,0 +1,34 @@ +package im.vector.matrix.android.internal.task + +import im.vector.matrix.android.api.util.Cancelable +import im.vector.matrix.android.internal.util.CancelableCoroutine +import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import timber.log.Timber +import kotlin.coroutines.EmptyCoroutineContext + +internal class TaskExecutor(private val coroutineDispatchers: MatrixCoroutineDispatchers) { + + fun execute(task: ConfigurableTask): Cancelable { + + val job = GlobalScope.launch(task.callbackThread.toDispatcher()) { + val resultOrFailure = withContext(task.executionThread.toDispatcher()) { + Timber.v("Executing ${task.javaClass} on ${Thread.currentThread().name}") + task.execute(task.params) + } + resultOrFailure.fold({ task.callback.onFailure(it) }, { task.callback.onSuccess(it) }) + } + return CancelableCoroutine(job) + } + + private fun TaskThread.toDispatcher() = when (this) { + TaskThread.MAIN -> coroutineDispatchers.main + TaskThread.COMPUTATION -> coroutineDispatchers.computation + TaskThread.IO -> coroutineDispatchers.io + TaskThread.CALLER -> EmptyCoroutineContext + } + + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/TaskThread.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/TaskThread.kt new file mode 100644 index 00000000..ade3d84d --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/task/TaskThread.kt @@ -0,0 +1,8 @@ +package im.vector.matrix.android.internal.task + +internal enum class TaskThread { + MAIN, + COMPUTATION, + IO, + CALLER +} \ No newline at end of file