Skip to content

Commit

Permalink
Refactor sync
Browse files Browse the repository at this point in the history
  • Loading branch information
bubelov committed Apr 28, 2024
1 parent 5f6e165 commit 4075919
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 48 deletions.
3 changes: 3 additions & 0 deletions app/src/main/kotlin/conf/ConfRepo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class ConfRepo(

val conf: StateFlow<Conf> = _conf.asStateFlow()

val current: Conf
get() = conf.value

init {
conf
.onEach { queries.insertOrReplace(it) }
Expand Down
6 changes: 1 addition & 5 deletions app/src/main/kotlin/map/MapModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,7 @@ class MapModel(

fun syncElements() {
viewModelScope.launch {
runCatching {
if (!sync.active.value) {
sync.sync()
}
}
sync.sync(doNothingIfAlreadySyncing = true)
}
}

Expand Down
61 changes: 21 additions & 40 deletions app/src/main/kotlin/sync/Sync.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package sync

import android.util.Log
import area.AreasRepo
import conf.ConfRepo
import reports.ReportsRepo
Expand All @@ -10,50 +9,38 @@ import event.EventsRepo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import time.now
import user.UsersRepo
import java.time.Duration
import java.time.ZoneOffset
import java.time.ZonedDateTime

class Sync(
private val areasRepo: AreasRepo,
private val confRepo: ConfRepo,
private val elementsRepo: ElementsRepo,
private val reportsRepo: ReportsRepo,
private val usersRepo: UsersRepo,
private val eventsRepo: EventsRepo,
private val conf: ConfRepo,
private val syncNotificationController: SyncNotificationController,
) {
private val mutex = Mutex()

private val _active = MutableStateFlow(false)
val active = _active.asStateFlow()

suspend fun sync() {
_active.update { true }
val startedAt = ZonedDateTime.now(ZoneOffset.UTC)
val lastSyncFinishedAt = confRepo.conf.value.lastSyncDate

if (lastSyncFinishedAt != null
&& Duration.between(lastSyncFinishedAt, startedAt).toMinutes() < 1
) {
_active.update { false }
return
suspend fun sync(doNothingIfAlreadySyncing: Boolean) = withContext(Dispatchers.IO) {
if (doNothingIfAlreadySyncing && mutex.isLocked) {
return@withContext
}

var syncReport: SyncReport? = null
mutex.withLock {
runCatching {
val startedAt = now()

runCatching {
withContext(Dispatchers.IO) {
if (elementsRepo.selectCount() == 0L && elementsRepo.hasBundledElements()) {
elementsRepo.fetchBundledElements().getOrThrow()
}
}

withContext(Dispatchers.IO) {
val elementsReport = async { elementsRepo.sync().getOrThrow() }
val reportsReport = async { reportsRepo.sync().getOrThrow() }
val areasReport = async { areasRepo.sync().getOrThrow() }
Expand All @@ -68,32 +55,26 @@ class Sync(
eventsReport,
).awaitAll()

syncReport = SyncReport(
val fullReport = SyncReport(
startedAt = startedAt,
finishedAt = ZonedDateTime.now(ZoneOffset.UTC),
newElements = elementsReport.await().newElements,
updatedElements = elementsReport.await().updatedElements,
newEvents = eventsReport.await().newEvents,
updatedEvents = eventsReport.await().updatedEvents,
)

syncNotificationController.showPostSyncNotifications(
report = fullReport,
conf = conf.current,
)
}.onSuccess {
conf.update { it.copy(lastSyncDate = now()) }
}.onFailure {
syncNotificationController.showSyncFailedNotification(it)
}
}.onSuccess {
syncNotificationController.showPostSyncNotifications(
report = syncReport!!,
conf = confRepo.conf.value,
)
confRepo.update { it.copy(lastSyncDate = ZonedDateTime.now(ZoneOffset.UTC)) }
_active.update { false }
}.onFailure {
Log.e(TAG, "Sync failed", it)
syncNotificationController.showSyncFailedNotification(it)
_active.update { false }
}
}

companion object {
private const val TAG = "sync"
}
}

data class SyncReport(
Expand Down
4 changes: 1 addition & 3 deletions app/src/main/kotlin/sync/SyncWorker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ class SyncWorker(context: Context, workerParams: WorkerParameters) : Worker(cont
return Result.retry()
}

if (!sync.active.value) {
sync.sync()
}
sync.sync(doNothingIfAlreadySyncing = true)

return Result.success()
}
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/kotlin/time/ZonedDateTimeExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package time

import java.time.ZoneOffset
import java.time.ZonedDateTime

fun now(zone: ZoneOffset = ZoneOffset.UTC) = ZonedDateTime.now(zone)

0 comments on commit 4075919

Please sign in to comment.