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 import java.util.concurrent.TimeUnit
sealed class PluginUpdateStatus { sealed class PluginUpdateStatus {
val timestamp = System.currentTimeMillis()
object LatestVersionInstalled : PluginUpdateStatus() object LatestVersionInstalled : PluginUpdateStatus()
class Update(val pluginDescriptor: IdeaPluginDescriptor, class Update(val pluginDescriptor: IdeaPluginDescriptor,
@@ -74,20 +76,22 @@ sealed class PluginUpdateStatus {
} }
class KotlinPluginUpdater(val propertiesComponent: PropertiesComponent) : Disposable { 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 var updateDelay = INITIAL_UPDATE_DELAY
private val alarm = Alarm(Alarm.ThreadToUse.POOLED_THREAD, this) private val alarm = Alarm(Alarm.ThreadToUse.POOLED_THREAD, this)
private val notificationGroup = NotificationGroup("Kotlin plugin updates", NotificationDisplayType.STICKY_BALLOON, true) private val notificationGroup = NotificationGroup("Kotlin plugin updates", NotificationDisplayType.STICKY_BALLOON, true)
@Volatile private var checkQueued = false @Volatile private var checkQueued = false
@Volatile private var lastStatus: PluginUpdateStatus? = null @Volatile private var lastUpdateStatus: PluginUpdateStatus? = null
fun kotlinFileEdited() { fun kotlinFileEdited() {
if (ApplicationManager.getApplication().isUnitTestMode) return if (ApplicationManager.getApplication().isUnitTestMode) return
if (!UpdateSettings.getInstance().isCheckNeeded) return if (!UpdateSettings.getInstance().isCheckNeeded) return
val lastUpdateTime = java.lang.Long.parseLong(propertiesComponent.getValue(PROPERTY_NAME, "0")) 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 -> queueUpdateCheck { updateStatus ->
when (updateStatus) { when (updateStatus) {
is PluginUpdateStatus.Update -> notifyPluginUpdateAvailable(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) { private fun updateCheck(callback: (PluginUpdateStatus) -> Boolean) {
var updateStatus: PluginUpdateStatus var updateStatus: PluginUpdateStatus
try { try {
@@ -127,7 +144,7 @@ class KotlinPluginUpdater(val propertiesComponent: PropertiesComponent) : Dispos
updateStatus = PluginUpdateStatus.fromException("Kotlin plugin update check failed", e) updateStatus = PluginUpdateStatus.fromException("Kotlin plugin update check failed", e)
} }
lastStatus = updateStatus lastUpdateStatus = updateStatus
checkQueued = false checkQueued = false
if (updateStatus !is PluginUpdateStatus.CheckFailed) { 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.getRuntimeJar
import org.jetbrains.kotlin.idea.framework.getTestJar import org.jetbrains.kotlin.idea.framework.getTestJar
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import java.awt.event.ComponentAdapter
import java.awt.event.ComponentEvent
import java.text.MessageFormat import java.text.MessageFormat
import java.util.* import java.util.*
import javax.swing.Icon import javax.swing.Icon
@@ -178,7 +180,7 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
private fun createUpdatePluginLink(answer: ErrorNotificationPanel) { private fun createUpdatePluginLink(answer: ErrorNotificationPanel) {
answer.createProgressAction(" Check...", "Update plugin") { link, updateLink -> answer.createProgressAction(" Check...", "Update plugin") { link, updateLink ->
KotlinPluginUpdater.getInstance().runUpdateCheck { pluginUpdateStatus -> KotlinPluginUpdater.getInstance().runCachedUpdate { pluginUpdateStatus ->
when (pluginUpdateStatus) { when (pluginUpdateStatus) {
is PluginUpdateStatus.Update -> { is PluginUpdateStatus.Update -> {
link.isVisible = false link.isVisible = false
@@ -300,7 +302,17 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
val successLink = createActionLabel(successLinkText, { }) val successLink = createActionLabel(successLinkText, { })
successLink.isVisible = false 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)
}
}
})
} }
} }