Remove not used emits
This commit is contained in:
@@ -2,15 +2,9 @@ package ru.fincode.tsudesk.core.common.model
|
|||||||
|
|
||||||
sealed interface DataResult<out T> {
|
sealed interface DataResult<out T> {
|
||||||
|
|
||||||
data class Cache<T>(
|
data class Data<T>(
|
||||||
val data: T
|
val data: T, val refreshedFromNetwork: Boolean
|
||||||
) : DataResult<T>
|
) : DataResult<T>
|
||||||
|
|
||||||
data class Network<T>(
|
data class Error(val throwable: Throwable) : DataResult<Nothing>
|
||||||
val data: T
|
|
||||||
) : DataResult<T>
|
|
||||||
|
|
||||||
data class Error(
|
|
||||||
val throwable: Throwable
|
|
||||||
) : DataResult<Nothing>
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
package ru.fincode.tsudesk.feature.schedule.data
|
package ru.fincode.tsudesk.feature.schedule.data
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.channelFlow
|
import kotlinx.coroutines.flow.channelFlow
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.fincode.tsudesk.core.common.model.DataResult
|
import ru.fincode.tsudesk.core.common.model.DataResult
|
||||||
import ru.fincode.tsudesk.core.common.model.DataResult.Error
|
|
||||||
import ru.fincode.tsudesk.core.network.model.NetworkResult
|
import ru.fincode.tsudesk.core.network.model.NetworkResult
|
||||||
import ru.fincode.tsudesk.core.network.model.map
|
import ru.fincode.tsudesk.core.network.model.map
|
||||||
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleLocalDataSource
|
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleLocalDataSource
|
||||||
@@ -17,6 +15,7 @@ import ru.fincode.tsudesk.feature.schedule.data.mapper.ScheduleNetworkMapper
|
|||||||
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleEntity
|
||||||
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleType
|
import ru.fincode.tsudesk.feature.schedule.domain.model.ScheduleType
|
||||||
import ru.fincode.tsudesk.feature.schedule.domain.repository.ScheduleRepository
|
import ru.fincode.tsudesk.feature.schedule.domain.repository.ScheduleRepository
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ScheduleRepositoryImpl @Inject constructor(
|
class ScheduleRepositoryImpl @Inject constructor(
|
||||||
@@ -25,7 +24,6 @@ class ScheduleRepositoryImpl @Inject constructor(
|
|||||||
private val mapper: ScheduleNetworkMapper
|
private val mapper: ScheduleNetworkMapper
|
||||||
) : ScheduleRepository {
|
) : ScheduleRepository {
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
override fun observeSchedule(type: ScheduleType): Flow<DataResult<ScheduleEntity>> =
|
override fun observeSchedule(type: ScheduleType): Flow<DataResult<ScheduleEntity>> =
|
||||||
channelFlow {
|
channelFlow {
|
||||||
val key = when (type) {
|
val key = when (type) {
|
||||||
@@ -33,39 +31,37 @@ class ScheduleRepositoryImpl @Inject constructor(
|
|||||||
is ScheduleType.Teacher -> ScheduleCacheKey.teacher(type.name)
|
is ScheduleType.Teacher -> ScheduleCacheKey.teacher(type.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// кэш -> UI
|
// Маркер: "следующий DB-emit считать пришедшим после сети"
|
||||||
|
val markNextAsNetwork = AtomicBoolean(false)
|
||||||
|
|
||||||
val cacheJob = launch {
|
val cacheJob = launch {
|
||||||
local.observeSchedule(key).collect { cached ->
|
local.observeSchedule(key).collect { cached ->
|
||||||
if (cached != null) send(DataResult.Cache(cached))
|
if (cached != null) {
|
||||||
|
val flag = markNextAsNetwork.getAndSet(false)
|
||||||
|
trySend(DataResult.Data(cached, refreshedFromNetwork = flag))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val networkResult: NetworkResult<ScheduleEntity> = when (type) {
|
// refresh: сеть -> БД, без эмита сетевых данных
|
||||||
is ScheduleType.Group ->
|
launch {
|
||||||
remote.loadScheduleByGroup(type.number).map(mapper::invoke)
|
val net: NetworkResult<ScheduleEntity> = when (type) {
|
||||||
|
is ScheduleType.Group -> remote.loadScheduleByGroup(type.number)
|
||||||
|
.map(mapper::invoke)
|
||||||
|
|
||||||
is ScheduleType.Teacher ->
|
is ScheduleType.Teacher -> remote.loadScheduleByTeacher(type.name)
|
||||||
remote.loadScheduleByTeacher(type.name).map(mapper::invoke)
|
.map(mapper::invoke)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (networkResult) {
|
when (net) {
|
||||||
is NetworkResult.Success -> {
|
is NetworkResult.Success -> {
|
||||||
// (опционально) сразу отдать сетевой результат
|
local.saveSchedule(key, net.data) // записали
|
||||||
send(DataResult.Network(networkResult.data))
|
markNextAsNetwork.set(true) // следующий DB emit пометить
|
||||||
|
|
||||||
// single source of truth -> сохраняем в БД
|
|
||||||
local.saveSchedule(key, networkResult.data)
|
|
||||||
|
|
||||||
// дать Room время эмитнуть обновление
|
|
||||||
kotlinx.coroutines.yield()
|
|
||||||
|
|
||||||
// закрываем поток по твоему требованию
|
|
||||||
close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is NetworkResult.Error -> {
|
is NetworkResult.Error -> {
|
||||||
send(Error(Throwable(networkResult.error.toString())))
|
trySend(DataResult.Error(Throwable(net.error.toString())))
|
||||||
close()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package ru.fincode.tsudesk.feature.schedule.data.local
|
|||||||
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import ru.fincode.tsudesk.core.database.schedule.ScheduleDao
|
import ru.fincode.tsudesk.core.database.schedule.ScheduleDao
|
||||||
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleLocalDataSource
|
import ru.fincode.tsudesk.feature.schedule.data.datasource.ScheduleLocalDataSource
|
||||||
import ru.fincode.tsudesk.feature.schedule.data.mapper.toCache
|
import ru.fincode.tsudesk.feature.schedule.data.mapper.toCache
|
||||||
@@ -29,6 +30,7 @@ class ScheduleLocalDataSourceImpl @Inject constructor(
|
|||||||
.combine(dao.observeLessons(key)) { schedule, lessons ->
|
.combine(dao.observeLessons(key)) { schedule, lessons ->
|
||||||
schedule?.toDomain(lessons)
|
schedule?.toDomain(lessons)
|
||||||
}
|
}
|
||||||
|
.distinctUntilChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun removeSchedule(key: String) {
|
override suspend fun removeSchedule(key: String) {
|
||||||
|
|||||||
Reference in New Issue
Block a user