Cache and postpone requests for plugin update status from UnsupportedAbiVersion notification

This commit is contained in:
Nikolay Krasko
2016-03-02 21:45:25 +03:00
parent 33b65ec692
commit b8ac6e27f5
2 changed files with 35 additions and 6 deletions
@@ -48,6 +48,8 @@ import java.net.URLEncoder
import java.util.concurrent.TimeUnit
sealed class PluginUpdateStatus {
val timestamp = System.currentTimeMillis()
object LatestVersionInstalled : PluginUpdateStatus()
class Update(val pluginDescriptor: IdeaPluginDescriptor,
@@ -74,20 +76,22 @@ sealed class PluginUpdateStatus {
}
class KotlinPluginUpdater(val propertiesComponent: PropertiesComponent) : Disposable {
private val INITIAL_UPDATE_DELAY = 5000L
private val INITIAL_UPDATE_DELAY = 2000L
private val CACHED_REQUEST_DELAY = TimeUnit.DAYS.toMillis(1)
private var updateDelay = INITIAL_UPDATE_DELAY
private val alarm = Alarm(Alarm.ThreadToUse.POOLED_THREAD, this)
private val notificationGroup = NotificationGroup("Kotlin plugin updates", NotificationDisplayType.STICKY_BALLOON, true)
@Volatile private var checkQueued = false
@Volatile private var lastStatus: PluginUpdateStatus? = null
@Volatile private var lastUpdateStatus: PluginUpdateStatus? = null
fun kotlinFileEdited() {
if (ApplicationManager.getApplication().isUnitTestMode) return
if (!UpdateSettings.getInstance().isCheckNeeded) return
val lastUpdateTime = java.lang.Long.parseLong(propertiesComponent.getValue(PROPERTY_NAME, "0"))
if (lastUpdateTime == 0L || System.currentTimeMillis() - lastUpdateTime > TimeUnit.DAYS.toMillis(1)) {
if (lastUpdateTime == 0L || System.currentTimeMillis() - lastUpdateTime > CACHED_REQUEST_DELAY) {
queueUpdateCheck { updateStatus ->
when (updateStatus) {
is PluginUpdateStatus.Update -> notifyPluginUpdateAvailable(updateStatus)
@@ -113,6 +117,19 @@ class KotlinPluginUpdater(val propertiesComponent: PropertiesComponent) : Dispos
}
}
fun runCachedUpdate(callback: (PluginUpdateStatus) -> Boolean) {
ApplicationManager.getApplication().assertIsDispatchThread()
val cachedStatus = lastUpdateStatus
if (cachedStatus != null && System.currentTimeMillis() - cachedStatus.timestamp < CACHED_REQUEST_DELAY) {
if (cachedStatus !is PluginUpdateStatus.CheckFailed) {
callback(cachedStatus)
return
}
}
queueUpdateCheck(callback)
}
private fun updateCheck(callback: (PluginUpdateStatus) -> Boolean) {
var updateStatus: PluginUpdateStatus
try {
@@ -127,7 +144,7 @@ class KotlinPluginUpdater(val propertiesComponent: PropertiesComponent) : Dispos
updateStatus = PluginUpdateStatus.fromException("Kotlin plugin update check failed", e)
}
lastStatus = updateStatus
lastUpdateStatus = updateStatus
checkQueued = false
if (updateStatus !is PluginUpdateStatus.CheckFailed) {
@@ -52,6 +52,8 @@ import org.jetbrains.kotlin.idea.framework.getReflectJar
import org.jetbrains.kotlin.idea.framework.getRuntimeJar
import org.jetbrains.kotlin.idea.framework.getTestJar
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import java.awt.event.ComponentAdapter
import java.awt.event.ComponentEvent
import java.text.MessageFormat
import java.util.*
import javax.swing.Icon
@@ -178,7 +180,7 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
private fun createUpdatePluginLink(answer: ErrorNotificationPanel) {
answer.createProgressAction(" Check...", "Update plugin") { link, updateLink ->
KotlinPluginUpdater.getInstance().runUpdateCheck { pluginUpdateStatus ->
KotlinPluginUpdater.getInstance().runCachedUpdate { pluginUpdateStatus ->
when (pluginUpdateStatus) {
is PluginUpdateStatus.Update -> {
link.isVisible = false
@@ -300,7 +302,17 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
val successLink = createActionLabel(successLinkText, { })
successLink.isVisible = false
updater(label, successLink)
// Several notification panels can be created almost instantly but we want to postpone deferred checks until
// panels are actually visible on screen.
myLinksPanel.addComponentListener(object : ComponentAdapter() {
var isUpdaterCalled = false
override fun componentResized(p0: ComponentEvent?) {
if (!isUpdaterCalled) {
isUpdaterCalled = true
updater(label, successLink)
}
}
})
}
}