Commit 10345946 authored by Ricki Hirner's avatar Ricki Hirner 🐑

Improve collection sync for contacts

parent be2d1027
Pipeline #21288739 passed with stages
in 7 minutes and 43 seconds
......@@ -18,7 +18,7 @@ android {
defaultConfig {
applicationId "at.bitfire.davdroid"
versionCode 214
versionCode 215
buildConfigField "long", "buildTime", System.currentTimeMillis() + "L"
buildConfigField "boolean", "customCerts", "true"
......@@ -33,7 +33,7 @@ android {
productFlavors {
standard {
versionName "1.11.1-ose"
versionName "1.12-beta1-ose"
buildConfigField "boolean", "customCerts", "true"
}
......
......@@ -9,6 +9,7 @@
package at.bitfire.davdroid.syncadapter
import android.accounts.Account
import android.content.ContentResolver
import android.content.Context
import android.content.SyncResult
import android.os.Bundle
......@@ -43,6 +44,15 @@ abstract class BaseDavSyncManager<ResourceType: LocalResource<*>, out Collection
localCollection: CollectionType
): SyncManager<ResourceType, CollectionType>(context, settings, account, accountSettings, extras, authority, syncResult, localCollection), AutoCloseable {
companion object {
/**
* How many updates are requested per collection-sync REPORT. We use a rather small number
* because the response has to be parsed and held in memory, which is a spare resource on
* handheld devices.
*/
const val COLLECTION_SYNC_LIMIT = 1
}
protected val httpClient = HttpClient.Builder(context, settings, accountSettings).build()
protected lateinit var collectionURL: HttpUrl
......@@ -149,6 +159,11 @@ abstract class BaseDavSyncManager<ResourceType: LocalResource<*>, out Collection
}
override fun syncRequired(): Boolean {
if (syncAlgorithm() == SyncAlgorithm.PROPFIND_REPORT && extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL)) {
Logger.log.info("Manual sync in PROPFIND/REPORT mode, forcing sync")
return true
}
val localState = localCollection.lastSyncState
val remoteState = syncState(false)
Logger.log.info("Local sync state = $localState, remote sync state = $remoteState")
......@@ -216,18 +231,20 @@ abstract class BaseDavSyncManager<ResourceType: LocalResource<*>, out Collection
}
override fun listRemoteChanges(state: SyncState?): RemoteChanges {
//try {
/*try {
davCollection.reportChanges(
state?.takeIf { state.type == SyncState.Type.SYNC_TOKEN }?.value,
false, null,
false, COLLECTION_SYNC_LIMIT,
GetETag.NAME)
/*} catch(e: HttpException) {
if (e.status in arrayOf(500,507))
} catch(e: HttpException) {
if (e.status == 507)*/
// some servers don't like the limit, try again without
davCollection.reportChanges(
state?.takeIf { state.type == SyncState.Type.SYNC_TOKEN }?.value,
false, null,
GetETag.NAME)
/*else
throw e
}*/
var syncToken: String? = null
......
......@@ -132,37 +132,35 @@ abstract class SyncManager<out ResourceType: LocalResource<*>, out CollectionTyp
Logger.log.info("Post-processing")
postProcess()
Logger.log.info("Saving sync state")
Logger.log.log(Level.INFO, "Saving sync state", changes.state)
localCollection.lastSyncState = changes.state
}
SyncAlgorithm.COLLECTION_SYNC -> {
var initialSync = false
val lastSyncState = localCollection.lastSyncState?.takeIf { it.type == SyncState.Type.SYNC_TOKEN }
if (lastSyncState == null) {
var syncState = localCollection.lastSyncState?.takeIf { it.type == SyncState.Type.SYNC_TOKEN }
if (syncState == null) {
Logger.log.info("Starting initial sync")
initialSync = true
resetPresentRemotely()
}
if (lastSyncState?.initialSync == true) {
if (syncState?.initialSync == true) {
Logger.log.info("Continuing initial sync")
initialSync = true
}
Logger.log.info("Listing changes since $lastSyncState")
var changes = listRemoteChanges(lastSyncState)
do {
Logger.log.info("Listing changes since $syncState")
val changes = listRemoteChanges(syncState)
Logger.log.info("Processing received changes")
processRemoteChanges(changes)
// save sync state and keep whether we're in initial sync
val newState = changes.state
newState?.initialSync = initialSync
Logger.log.log(Level.INFO, "Saving sync state", newState)
localCollection.lastSyncState = newState
Logger.log.info("Listing changes since ${changes.state}")
changes = listRemoteChanges(changes.state)
syncState = changes.state ?: throw DavException("Received sync-collection without sync-token")
syncState.initialSync = initialSync
Logger.log.log(Level.INFO, "Saving sync state", syncState)
localCollection.lastSyncState = syncState
} while (changes.furtherChanges)
Logger.log.info("No more changes available on server")
......@@ -173,11 +171,9 @@ abstract class SyncManager<out ResourceType: LocalResource<*>, out CollectionTyp
deleteNotPresentRemotely()
// remove initial sync flag
lastSyncState?.let { state ->
state.initialSync = false
Logger.log.log(Level.INFO, "Saving sync state", state)
localCollection.lastSyncState = state
}
syncState!!.initialSync = false
Logger.log.log(Level.INFO, "Initial sync completed, saving sync state", syncState)
localCollection.lastSyncState = syncState
}
Logger.log.info("Post-processing")
......
......@@ -9,7 +9,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.dokka_version = '0.9.16'
ext.kotlin_version = '1.2.40'
ext.kotlin_version = '1.2.41'
repositories {
jcenter()
......
Subproject commit e1f6ce463c107f65541b8b5a0703ebb40978f27c
Subproject commit 7968c5eed261e610477ab14f8734bf38db78cef4
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment