mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-24 10:25:51 +03:00
Better coroutines management
This commit is contained in:
parent
1a967b6326
commit
95fd7190e4
12 changed files with 81 additions and 64 deletions
Binary file not shown.
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
|
@ -1,7 +1,7 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.0-rc-116'
|
||||
ext.kotlin_version = '1.3.0-rc-146'
|
||||
ext.koin_version = '1.0.1'
|
||||
repositories {
|
||||
google()
|
||||
|
@ -9,7 +9,7 @@ buildscript {
|
|||
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
|||
import im.vector.matrix.android.BuildConfig
|
||||
import im.vector.matrix.android.api.auth.Authenticator
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.thread.MainThreadExecutor
|
||||
import im.vector.matrix.android.internal.auth.AuthModule
|
||||
import im.vector.matrix.android.internal.di.MatrixModule
|
||||
import im.vector.matrix.android.internal.di.NetworkModule
|
||||
|
@ -13,7 +12,6 @@ import org.koin.standalone.StandAloneContext.loadKoinModules
|
|||
import org.koin.standalone.inject
|
||||
import timber.log.Timber
|
||||
import timber.log.Timber.DebugTree
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
|
||||
class Matrix(matrixOptions: MatrixOptions) : KoinComponent {
|
||||
|
@ -38,5 +36,4 @@ class Matrix(matrixOptions: MatrixOptions) : KoinComponent {
|
|||
|
||||
}
|
||||
|
||||
data class MatrixOptions(val context: Context,
|
||||
val mainExecutor: Executor = MainThreadExecutor())
|
||||
data class MatrixOptions(val context: Context)
|
||||
|
|
|
@ -18,7 +18,7 @@ class AuthModule(private val context: Context) : Module {
|
|||
override fun invoke(): ModuleDefinition = module {
|
||||
|
||||
single {
|
||||
DefaultAuthenticator(get(), get(), get(), get()) as Authenticator
|
||||
DefaultAuthenticator(get(), get(), get()) as Authenticator
|
||||
}
|
||||
|
||||
single(name = AUTH_BOX_STORE) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package im.vector.matrix.android.internal.auth
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.leftIfNull
|
||||
import com.squareup.moshi.Moshi
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.auth.Authenticator
|
||||
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||
|
@ -17,10 +17,10 @@ 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 retrofit2.Retrofit
|
||||
|
||||
class DefaultAuthenticator(private val retrofitBuilder: Retrofit.Builder,
|
||||
private val jsonMapper: Moshi,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val sessionParamsStore: SessionParamsStore) : Authenticator {
|
||||
|
||||
|
@ -35,28 +35,37 @@ class DefaultAuthenticator(private val retrofitBuilder: Retrofit.Builder,
|
|||
}
|
||||
}
|
||||
|
||||
override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig, login: String, password: String, callback: MatrixCallback<Session>): Cancelable {
|
||||
val authAPI = buildAuthAPI(homeServerConnectionConfig)
|
||||
override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
login: String,
|
||||
password: String,
|
||||
callback: MatrixCallback<Session>): Cancelable {
|
||||
|
||||
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
||||
val loginParams = PasswordLoginParams.userIdentifier(login, password, "Mobile")
|
||||
executeRequest<Credentials> {
|
||||
apiCall = authAPI.login(loginParams)
|
||||
moshi = jsonMapper
|
||||
dispatcher = coroutineDispatchers.io
|
||||
}.leftIfNull {
|
||||
Failure.Unknown(IllegalArgumentException("Credentials shouldn't not be null"))
|
||||
}.map {
|
||||
val sessionParams = SessionParams(it, homeServerConnectionConfig)
|
||||
sessionParamsStore.save(sessionParams)
|
||||
sessionParams
|
||||
}.map {
|
||||
DefaultSession(it)
|
||||
}.bimap(
|
||||
{ callback.onFailure(it) }, { callback.onSuccess(it) }
|
||||
)
|
||||
val sessionOrFailure = authenticate(homeServerConnectionConfig, login, password)
|
||||
sessionOrFailure.bimap({ callback.onFailure(it) }, { callback.onSuccess(it) })
|
||||
}
|
||||
return CancelableCoroutine(job)
|
||||
|
||||
}
|
||||
|
||||
private suspend fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
login: String,
|
||||
password: String): Either<Failure, Session> = withContext(coroutineDispatchers.io) {
|
||||
|
||||
val authAPI = buildAuthAPI(homeServerConnectionConfig)
|
||||
val loginParams = PasswordLoginParams.userIdentifier(login, password, "Mobile")
|
||||
executeRequest<Credentials> {
|
||||
apiCall = authAPI.login(loginParams)
|
||||
}.leftIfNull {
|
||||
Failure.Unknown(IllegalArgumentException("Credentials shouldn't not be null"))
|
||||
}.map {
|
||||
val sessionParams = SessionParams(it, homeServerConnectionConfig)
|
||||
sessionParamsStore.save(sessionParams)
|
||||
sessionParams
|
||||
}.map {
|
||||
DefaultSession(it)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package im.vector.matrix.android.internal.di
|
||||
|
||||
import im.vector.matrix.android.api.MatrixOptions
|
||||
import im.vector.matrix.android.api.thread.MainThreadExecutor
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
|
@ -19,7 +20,7 @@ class MatrixModule(private val options: MatrixOptions) : Module {
|
|||
}
|
||||
|
||||
single {
|
||||
MatrixCoroutineDispatchers(io = Dispatchers.IO, computation = Dispatchers.IO, main = options.mainExecutor.asCoroutineDispatcher())
|
||||
MatrixCoroutineDispatchers(io = Dispatchers.IO, computation = Dispatchers.IO, main = MainThreadExecutor().asCoroutineDispatcher())
|
||||
}
|
||||
}.invoke()
|
||||
}
|
|
@ -11,4 +11,4 @@ object MoshiProvider {
|
|||
return moshi
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package im.vector.matrix.android.internal.events.sync
|
||||
|
||||
import im.vector.matrix.android.api.events.Event
|
||||
import im.vector.matrix.android.internal.database.mapper.EventMapper
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
|
@ -23,8 +24,8 @@ class RoomSyncHandler(
|
|||
return
|
||||
}
|
||||
val roomEntities = ArrayList<RoomEntity>()
|
||||
roomSyncByRoom.forEach { roomId, roomSync ->
|
||||
val roomEntity = handleJoinedRoom(roomId, roomSync)
|
||||
roomSyncByRoom.forEach {
|
||||
val roomEntity = handleJoinedRoom(it.key, it.value)
|
||||
roomEntities.add(roomEntity)
|
||||
}
|
||||
roomBox.put(roomEntities)
|
||||
|
@ -40,22 +41,27 @@ class RoomSyncHandler(
|
|||
}
|
||||
roomEntity.membership = RoomEntity.Membership.JOINED
|
||||
if (roomSync.timeline != null) {
|
||||
val chunkEntity = ChunkEntity()
|
||||
chunkEntity.prevToken = roomSync.timeline.prevBatch
|
||||
roomSync.timeline.events
|
||||
.map { event -> EventMapper.map(event) }
|
||||
.forEach { chunkEntity.events.add(it) }
|
||||
val chunkEntity = eventListToChunk(roomSync.timeline.events, roomSync.timeline.prevBatch)
|
||||
roomEntity.chunks.add(chunkEntity)
|
||||
}
|
||||
|
||||
if (roomSync.state != null) {
|
||||
val chunkEntity = ChunkEntity()
|
||||
roomSync.state.events
|
||||
.map { event -> EventMapper.map(event) }
|
||||
.forEach { chunkEntity.events.add(it) }
|
||||
val chunkEntity = eventListToChunk(roomSync.state.events)
|
||||
roomEntity.chunks.add(chunkEntity)
|
||||
}
|
||||
return roomEntity
|
||||
}
|
||||
|
||||
private fun eventListToChunk(eventList: List<Event>,
|
||||
prevToken: String? = null,
|
||||
nextToken: String? = null): ChunkEntity {
|
||||
val chunkEntity = ChunkEntity()
|
||||
chunkEntity.prevToken = prevToken
|
||||
chunkEntity.nextToken = nextToken
|
||||
eventList
|
||||
.map { event -> EventMapper.map(event) }
|
||||
.forEach { chunkEntity.events.add(it) }
|
||||
return chunkEntity
|
||||
}
|
||||
|
||||
}
|
|
@ -24,7 +24,7 @@ class SyncModule : Module {
|
|||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
Synchronizer(get(), get(), get(), get())
|
||||
Synchronizer(get(), get(), get())
|
||||
}
|
||||
|
||||
}.invoke()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package im.vector.matrix.android.internal.events.sync
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.internal.events.sync.data.SyncResponse
|
||||
|
@ -11,30 +10,32 @@ 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
|
||||
|
||||
class Synchronizer(private val syncAPI: SyncAPI,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val jsonMapper: Moshi,
|
||||
private val syncResponseHandler: SyncResponseHandler) {
|
||||
|
||||
fun synchronize(callback: MatrixCallback<SyncResponse>): Cancelable {
|
||||
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
||||
val params = HashMap<String, String>()
|
||||
val filterBody = FilterBody()
|
||||
FilterUtil.enableLazyLoading(filterBody, true)
|
||||
params["timeout"] = "0"
|
||||
params["filter"] = filterBody.toJSONString()
|
||||
val syncResponse = executeRequest<SyncResponse> {
|
||||
apiCall = syncAPI.sync(params)
|
||||
moshi = jsonMapper
|
||||
dispatcher = coroutineDispatchers.io
|
||||
}.map {
|
||||
syncResponseHandler.handleResponse(it, null, false)
|
||||
it
|
||||
}
|
||||
syncResponse.bimap({ callback.onFailure(it) }, { callback.onSuccess(it) })
|
||||
val syncOrFailure = synchronize()
|
||||
syncOrFailure.bimap({ callback.onFailure(it) }, { callback.onSuccess(it) })
|
||||
}
|
||||
return CancelableCoroutine(job)
|
||||
}
|
||||
|
||||
private suspend fun synchronize() = withContext(coroutineDispatchers.io) {
|
||||
val params = HashMap<String, String>()
|
||||
val filterBody = FilterBody()
|
||||
FilterUtil.enableLazyLoading(filterBody, true)
|
||||
params["timeout"] = "0"
|
||||
params["filter"] = filterBody.toJSONString()
|
||||
executeRequest<SyncResponse> {
|
||||
apiCall = syncAPI.sync(params)
|
||||
}.map {
|
||||
syncResponseHandler.handleResponse(it, null, false)
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,9 +4,9 @@ import arrow.core.Either
|
|||
import com.squareup.moshi.Moshi
|
||||
import im.vector.matrix.android.api.failure.Failure
|
||||
import im.vector.matrix.android.api.failure.MatrixError
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.Response
|
||||
import java.io.IOException
|
||||
|
@ -15,13 +15,11 @@ suspend inline fun <DATA> executeRequest(block: Request<DATA>.() -> Unit) = Requ
|
|||
|
||||
class Request<DATA> {
|
||||
|
||||
var moshi: Moshi = MoshiProvider.providesMoshi()
|
||||
lateinit var apiCall: Deferred<Response<DATA>>
|
||||
lateinit var moshi: Moshi
|
||||
lateinit var dispatcher: CoroutineDispatcher
|
||||
|
||||
suspend fun execute(): Either<Failure, DATA?> = withContext(dispatcher) {
|
||||
return@withContext try {
|
||||
|
||||
suspend fun execute(): Either<Failure, DATA?> = coroutineScope {
|
||||
try {
|
||||
val response = apiCall.await()
|
||||
if (response.isSuccessful) {
|
||||
val result = response.body()
|
||||
|
|
Loading…
Reference in a new issue