fix settings sync auto tests + light refactoring

GitOrigin-RevId: 57fda7dda9be6b2574ed6ca23c0def61fb967fae
This commit is contained in:
Sergey Pak
2024-07-01 19:44:54 +00:00
committed by intellij-monorepo-bot
parent 9738e552e7
commit eb2aa77226
3 changed files with 55 additions and 29 deletions
@@ -6,6 +6,7 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.runBlockingCancellable
import com.intellij.platform.util.progress.withProgressText
import com.intellij.settingsSync.SettingsSyncBridge.PushRequestMode.*
import com.intellij.settingsSync.statistics.SettingsSyncEventsStatistics
import com.intellij.util.containers.ContainerUtil
@@ -39,6 +40,10 @@ class SettingsSyncBridge(
@Volatile
private var queueJob: Job? = null
val isInitialized
get() = queueJob != null
private val eventsLock = ReentrantLock()
private val settingsChangeListener = object : SettingsSyncEventListener {
@@ -76,24 +81,27 @@ class SettingsSyncBridge(
internal fun initialize(initMode: InitMode) {
coroutineScope.launch {
try {
settingsLog.initialize()
withProgressText(SettingsSyncBundle.message(initMode.messageKey)) {
try {
settingsLog.initialize()
// the queue is not activated initially => events will be collected but not processed until we perform all initialization tasks
SettingsSyncEvents.getInstance().addListener(settingsChangeListener)
ideMediator.activateStreamProvider()
// the queue is not activated initially => events will be collected but not processed until we perform all initialization tasks
SettingsSyncEvents.getInstance().addListener(settingsChangeListener)
ideMediator.activateStreamProvider()
applyInitialChanges(initMode)
applyInitialChanges(initMode)
startQueue()
}
catch (ex: Exception) {
stopSyncingAndRollback(null, ex)
startQueue()
}
catch (ex: Exception) {
stopSyncingAndRollback(null, ex)
}
}
}
}
private fun startQueue() {
LOG.info("Starting settings sync queue")
queueJob = coroutineScope.launch {
while (true) {
processPendingEvents()
@@ -197,11 +205,18 @@ class SettingsSyncBridge(
})
}
internal sealed class InitMode {
object JustInit : InitMode()
class TakeFromServer(val cloudEvent: SyncSettingsEvent.CloudChange) : InitMode()
class MigrateFromOldStorage(val migration: SettingsSyncMigration) : InitMode()
object PushToServer : InitMode()
internal sealed class InitMode(val messageKey: String) {
object JustInit
: InitMode("enable.sync.check.server.data.progress")
class TakeFromServer(val cloudEvent: SyncSettingsEvent.CloudChange)
: InitMode("enable.sync.get.from.server.progress")
class MigrateFromOldStorage(val migration: SettingsSyncMigration)
: InitMode("enable.sync.check.server.data.progress")
object PushToServer
: InitMode("enable.sync.push.to.server.progress")
}
private suspend fun processExclusiveEvent(event: SyncSettingsEvent.ExclusiveEvent) {
@@ -239,7 +254,7 @@ class SettingsSyncBridge(
var mergeAndPushAfterProcessingEvents = true
while (pendingEvents.isNotEmpty()) {
val event = pendingEvents.removeAt(0)
LOG.debug("Processing event $event")
LOG.info("Processing event $event")
when (event) {
is SyncSettingsEvent.IdeChange -> {
settingsLog.applyIdeState(event.snapshot, "Local changes made in the IDE")
@@ -2,11 +2,16 @@ package com.intellij.settingsSync.config
import com.intellij.configurationStore.saveSettings
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task
import com.intellij.openapi.progress.runBlockingCancellable
import com.intellij.openapi.util.NlsContexts
import com.intellij.platform.util.progress.withProgressText
import com.intellij.settingsSync.*
import com.intellij.util.EventDispatcher
import kotlinx.coroutines.*
import java.util.*
internal class SettingsSyncEnabler {
@@ -64,12 +69,7 @@ internal class SettingsSyncEnabler {
fun pushSettingsToServer() {
val settingsSyncControls = SettingsSyncMain.getInstance().controls
object : Task.Modal(null, SettingsSyncBundle.message("enable.sync.push.to.server.progress"), false) {
override fun run(indicator: ProgressIndicator) {
// todo initialization must be modal but pushing to server can be made later
settingsSyncControls.bridge.initialize(SettingsSyncBridge.InitMode.PushToServer)
}
}.queue()
settingsSyncControls.bridge.initialize(SettingsSyncBridge.InitMode.PushToServer)
}
@@ -6,11 +6,9 @@ import com.intellij.openapi.ui.playback.commands.PlaybackCommandCoroutineAdapter
import com.intellij.settingsSync.*
import com.intellij.settingsSync.config.SettingsSyncEnabler
import com.jetbrains.performancePlugin.commands.Waiter
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import kotlinx.coroutines.*
import org.jetbrains.annotations.NonNls
import java.util.concurrent.TimeUnit
enum class EnableSettingSyncOptions {
GET, PUSH, NONE
@@ -67,15 +65,28 @@ class EnableSettingsSyncCommand(text: @NonNls String, line: Int) : PlaybackComma
})
settingsSyncEnabler.checkServerState()
serverRespondedOnCheck.await()
var startTime = System.currentTimeMillis()
while (!SettingsSyncMain.getInstance().controls.bridge.isInitialized) {
delay(50)
if (System.currentTimeMillis() - startTime > TimeUnit.SECONDS.toMillis(5)) {
throw Exception("Settings Sync initialization timeout exceeded")
}
}
if(SettingsSyncLocalSettings.getInstance().isCrossIdeSyncEnabled != isCrossIdeSync){
SettingsSyncLocalSettings.getInstance().isCrossIdeSyncEnabled = isCrossIdeSync
SettingsSyncEvents.getInstance().fireSettingsChanged(SyncSettingsEvent.CrossIdeSyncStateChanged(isCrossIdeSync))
}
//there is no event that cross-ide sync was enabled, so we need to check that file appears and wait a bit :(
Waiter.checkCondition {
CloudConfigServerCommunicator().isFileExists(CROSS_IDE_SYNC_MARKER_FILE) == isCrossIdeSync
startTime = System.currentTimeMillis()
while (CloudConfigServerCommunicator().isFileExists(CROSS_IDE_SYNC_MARKER_FILE) != isCrossIdeSync) {
delay(500)
if (System.currentTimeMillis() - startTime > TimeUnit.SECONDS.toMillis(5)) {
val fileExists = CloudConfigServerCommunicator().isFileExists(CROSS_IDE_SYNC_MARKER_FILE)
throw Exception("Cross-IDE sync marker file was not updated in 5 seconds. File exists=$fileExists, expected=$isCrossIdeSync")
}
}
delay(5000L)
}
}
}