fix ICS sync on app exit

GitOrigin-RevId: 38fb384ca65c7b526ddc7a85fc7c4555c0e624d1
This commit is contained in:
Vladimir Krivosheev
2025-02-11 21:18:12 +00:00
committed by intellij-monorepo-bot
parent 64998553e0
commit e2e90900a2
2 changed files with 39 additions and 32 deletions
+6 -8
View File
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.settingsRepository
import com.intellij.DynamicBundle
@@ -7,17 +7,15 @@ import org.jetbrains.annotations.PropertyKey
internal const val BUNDLE = "messages.IcsBundle"
object IcsBundle : DynamicBundle(BUNDLE) {
internal object IcsBundle {
private val bundle = DynamicBundle(IcsBundle::class.java, BUNDLE)
@Nls
@JvmStatic
fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String = getMessage(key, *params)
@JvmStatic
fun messagePointer(@PropertyKey(resourceBundle = BUNDLE) key: String,
vararg params: Any): java.util.function.Supplier<String> = getLazyMessage(key, *params)
fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String = bundle.getMessage(key, *params)
}
@Nls
fun icsMessage(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String {
internal fun icsMessage(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String {
return IcsBundle.message(key, *params)
}
+33 -24
View File
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.settingsRepository
import com.intellij.configurationStore.ComponentStoreImpl
@@ -8,9 +8,11 @@ import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.asContextElement
import com.intellij.openapi.components.ComponentManagerEx
import com.intellij.openapi.components.impl.stores.stateStore
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.runBlockingMaybeCancellable
import com.intellij.platform.ide.progress.ModalTaskOwner
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
import com.intellij.platform.util.progress.reportRawProgress
import com.intellij.util.ui.EDT
import kotlinx.coroutines.*
internal class AutoSyncManager(private val icsManager: IcsManager) {
@@ -45,27 +47,15 @@ internal class AutoSyncManager(private val icsManager: IcsManager) {
if (onAppExit) {
// called on final confirmed exit - no need to restore enabled state
enabled = false
catchAndLog {
runBlockingMaybeCancellable {
icsManager.runInAutoCommitDisabledMode {
val repositoryManager = icsManager.repositoryManager
val hasUpstream = repositoryManager.hasUpstream()
if (hasUpstream && !repositoryManager.canCommit()) {
LOG.warn("Auto sync skipped: repository is not committable")
return@runInAutoCommitDisabledMode
}
// on app exit fetch and push only if there are commits to push
// if no upstream - just update cloud schemes
if (hasUpstream && !repositoryManager.commit() && repositoryManager.getAheadCommitsCount() == 0 && icsManager.readOnlySourcesManager.repositories.isEmpty()) {
return@runInAutoCommitDisabledMode
}
// use explicit progress task to sync on app exit to make it clear why app is not exited immediately
icsManager.syncManager.sync(SyncType.MERGE, onAppExit = true)
}
if (EDT.isCurrentThreadEdt()) {
@Suppress("DialogTitleCapitalization")
runWithModalProgressBlocking(ModalTaskOwner.guess(), IcsBundle.message("task.sync.title")) {
doSyncOnAppExit()
}
}
runBlockingMaybeCancellable {
doSyncOnAppExit()
}
return
}
else if (ApplicationManager.getApplication().isDisposed) {
@@ -82,6 +72,26 @@ internal class AutoSyncManager(private val icsManager: IcsManager) {
}
}
private suspend fun doSyncOnAppExit() {
icsManager.runInAutoCommitDisabledMode {
val repositoryManager = icsManager.repositoryManager
val hasUpstream = repositoryManager.hasUpstream()
if (hasUpstream && !repositoryManager.canCommit()) {
LOG.warn("Auto sync skipped: repository is not committable")
return@runInAutoCommitDisabledMode
}
// on app exit fetch and push only if there are commits to push
// if no upstream - just update cloud schemes
if (hasUpstream && !repositoryManager.commit() && repositoryManager.getAheadCommitsCount() == 0 && icsManager.readOnlySourcesManager.repositories.isEmpty()) {
return@runInAutoCommitDisabledMode
}
// use an explicit progress task to sync on app exit to make it clear why the app is not exited immediately
icsManager.syncManager.sync(SyncType.MERGE, onAppExit = true)
}
}
private suspend fun doSync() {
val app = ApplicationManager.getApplication()
val repositoryManager = icsManager.repositoryManager
@@ -122,9 +132,8 @@ internal inline fun catchAndLog(asWarning: Boolean = false, runnable: () -> Unit
try {
runnable()
}
catch (_: ProcessCanceledException) {
}
catch (_: CancellationException) {
catch (e: CancellationException) {
throw e
}
catch (e: Throwable) {
if (asWarning || e is AuthenticationException || e is NoRemoteRepositoryException) {