Skip to content

Commit 7d4bca1

Browse files
committed
Move sync on collections change listener; add delay
1 parent 7f58df8 commit 7d4bca1

File tree

3 files changed

+62
-35
lines changed

3 files changed

+62
-35
lines changed

app/src/androidTest/kotlin/at/bitfire/davdroid/TestModules.kt

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,18 @@ import at.bitfire.davdroid.push.PushRegistrationWorkerManager
88
import at.bitfire.davdroid.repository.DavCollectionRepository
99
import at.bitfire.davdroid.startup.StartupPlugin
1010
import at.bitfire.davdroid.startup.TasksAppWatcher
11-
import at.bitfire.davdroid.sync.worker.SyncWorkerManager
1211
import dagger.Module
1312
import dagger.hilt.components.SingletonComponent
1413
import dagger.hilt.testing.TestInstallIn
1514
import dagger.multibindings.Multibinds
1615

17-
// remove SyncWorkerModule from Android tests
16+
// remove SyncOnCollectionsChangeListenerModule from Android tests
1817
@Module
1918
@TestInstallIn(
2019
components = [SingletonComponent::class],
21-
replaces = [SyncWorkerManager.SyncWorkerManagerModule::class]
20+
replaces = [SyncOnCollectionsChangeListenerModule::class]
2221
)
23-
abstract class TestSyncWorkerManagerModule {
22+
abstract class SyncOnCollectionsChangeListenerModule {
2423
// provides empty set of listeners
2524
@Multibinds
2625
abstract fun empty(): Set<DavCollectionRepository.OnChangeListener>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
3+
*/
4+
5+
package at.bitfire.davdroid.repository
6+
7+
import android.accounts.Account
8+
import at.bitfire.davdroid.sync.worker.SyncWorkerManager
9+
import dagger.Binds
10+
import dagger.Module
11+
import dagger.hilt.InstallIn
12+
import dagger.hilt.components.SingletonComponent
13+
import dagger.multibindings.IntoSet
14+
import kotlinx.coroutines.CoroutineScope
15+
import kotlinx.coroutines.Dispatchers
16+
import kotlinx.coroutines.Job
17+
import kotlinx.coroutines.delay
18+
import kotlinx.coroutines.launch
19+
import java.util.logging.Logger
20+
import javax.inject.Inject
21+
22+
/**
23+
* Enqueues a sync worker after a short delay when the collection list changes.
24+
*/
25+
class SyncOnCollectionsChangeListener @Inject constructor(
26+
private val workerManager: SyncWorkerManager,
27+
private val logger: Logger
28+
): DavCollectionRepository.OnChangeListener {
29+
30+
var delayedOneTimeSyncWorkerJob: Job? = null
31+
32+
override fun onCollectionsChanged(account: Account?) {
33+
account?.let {
34+
// Start sync after a short delay to avoid multiple syncs in a short time when multiple
35+
// collections change quickly, e.g. at collection refresh or users first time setup.
36+
delayedOneTimeSyncWorkerJob?.cancel()
37+
delayedOneTimeSyncWorkerJob = CoroutineScope(Dispatchers.IO).launch {
38+
delay(7000)
39+
logger.info("Collections changed, scheduling sync")
40+
workerManager.enqueueOneTimeAllAuthorities(it)
41+
}
42+
}
43+
}
44+
45+
46+
47+
/**
48+
* Hilt module that registers [SyncOnCollectionsChangeListener] in [DavCollectionRepository].
49+
*/
50+
@Module
51+
@InstallIn(SingletonComponent::class)
52+
interface SyncOnCollectionsChangeListenerModule {
53+
@Binds
54+
@IntoSet
55+
fun listener(impl: SyncOnCollectionsChangeListener): DavCollectionRepository.OnChangeListener
56+
}
57+
58+
}

app/src/main/kotlin/at/bitfire/davdroid/sync/worker/SyncWorkerManager.kt

+1-31
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import androidx.work.WorkManager
2525
import androidx.work.WorkQuery
2626
import androidx.work.WorkRequest
2727
import at.bitfire.davdroid.push.PushNotificationManager
28-
import at.bitfire.davdroid.repository.DavCollectionRepository
2928
import at.bitfire.davdroid.sync.SyncDataType
3029
import at.bitfire.davdroid.sync.TasksAppManager
3130
import at.bitfire.davdroid.sync.worker.BaseSyncWorker.Companion.INPUT_ACCOUNT_NAME
@@ -37,13 +36,8 @@ import at.bitfire.davdroid.sync.worker.BaseSyncWorker.Companion.INPUT_UPLOAD
3736
import at.bitfire.davdroid.sync.worker.BaseSyncWorker.Companion.InputResync
3837
import at.bitfire.davdroid.sync.worker.BaseSyncWorker.Companion.NO_RESYNC
3938
import at.bitfire.davdroid.sync.worker.BaseSyncWorker.Companion.commonTag
40-
import dagger.Binds
4139
import dagger.Lazy
42-
import dagger.Module
43-
import dagger.hilt.InstallIn
4440
import dagger.hilt.android.qualifiers.ApplicationContext
45-
import dagger.hilt.components.SingletonComponent
46-
import dagger.multibindings.IntoSet
4741
import kotlinx.coroutines.flow.Flow
4842
import kotlinx.coroutines.flow.map
4943
import java.util.concurrent.TimeUnit
@@ -149,7 +143,7 @@ class SyncWorkerManager @Inject constructor(
149143
}
150144
WorkManager.getInstance(context).enqueueUniqueWork(
151145
name,
152-
/* If sync is already running, just continue.
146+
/* If sync is already running, continue that sync and don't append a new one.
153147
Existing retried work will not be replaced (for instance when
154148
PeriodicSyncWorker enqueues another scheduled sync). */
155149
ExistingWorkPolicy.KEEP,
@@ -291,28 +285,4 @@ class SyncWorkerManager @Inject constructor(
291285
}
292286
}
293287

294-
/**
295-
* Listener that enqueues a push registration worker when the collection list changes.
296-
*/
297-
class CollectionsListener @Inject constructor(
298-
private val workerManager: SyncWorkerManager
299-
): DavCollectionRepository.OnChangeListener {
300-
301-
override fun onCollectionsChanged(account: Account?) {
302-
account?.let { workerManager.enqueueOneTimeAllAuthorities(it) }
303-
}
304-
305-
}
306-
307-
/**
308-
* Hilt module that registers [CollectionsListener] in [DavCollectionRepository].
309-
*/
310-
@Module
311-
@InstallIn(SingletonComponent::class)
312-
interface SyncWorkerManagerModule {
313-
@Binds
314-
@IntoSet
315-
fun listener(impl: CollectionsListener): DavCollectionRepository.OnChangeListener
316-
}
317-
318288
}

0 commit comments

Comments
 (0)