From 5daf7f05374456b1861b08a7bdbad7c2bc3e2bbb Mon Sep 17 00:00:00 2001 From: tangcent Date: Mon, 18 Sep 2023 21:39:11 +0800 Subject: [PATCH] amend: remove CompensateRateLimiter --- .../idea/plugin/dialog/ApiCallDialog.kt | 28 +++--- .../plugin/utils/CompensateRateLimiter.kt | 91 ------------------- .../plugin/utils/CompensateRateLimiterTest.kt | 83 ----------------- 3 files changed, 12 insertions(+), 190 deletions(-) delete mode 100644 idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/utils/CompensateRateLimiter.kt delete mode 100644 idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/utils/CompensateRateLimiterTest.kt diff --git a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/dialog/ApiCallDialog.kt b/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/dialog/ApiCallDialog.kt index 705e41b2..b65a7a51 100644 --- a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/dialog/ApiCallDialog.kt +++ b/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/dialog/ApiCallDialog.kt @@ -22,13 +22,13 @@ import com.itangcent.idea.binder.DbBeanBinderFactory import com.itangcent.idea.icons.EasyIcons import com.itangcent.idea.icons.iconOnly import com.itangcent.idea.plugin.api.call.ApiCallUI -import com.itangcent.idea.plugin.utils.CompensateRateLimiter import com.itangcent.idea.psi.resourceClass import com.itangcent.idea.psi.resourceMethod import com.itangcent.idea.swing.onSelect import com.itangcent.idea.swing.onTextChange import com.itangcent.idea.utils.* import com.itangcent.intellij.extend.rx.ThrottleHelper +import com.itangcent.intellij.extend.rx.throttle import com.itangcent.intellij.extend.withBoundary import com.itangcent.intellij.file.LocalFileRepository import com.itangcent.intellij.psi.PsiClassUtils @@ -105,8 +105,6 @@ class ApiCallDialog : ContextDialog(), ApiCallUI { { NULL_REQUEST_INFO_CACHE } } - private val rateLimiter = CompensateRateLimiter.create(10) - private val throttleHelper = ThrottleHelper() private val requestChangeThrottle = throttleHelper.build("request") @@ -203,24 +201,22 @@ class ApiCallDialog : ContextDialog(), ApiCallUI { } } - private fun resize() { - rateLimiter.tryAcquire { - actionContext.runInSwingUI { - val rightWidth = this.contentPane.width - this.apisListPanel.width + private val resize = { + actionContext.runInSwingUI { + val rightWidth = this.contentPane.width - this.apisListPanel.width - val rightPanel = this.rightPanel - rightPanel.setSizeIfNecessary(rightWidth, this.contentPane.height - 6) + val rightPanel = this.rightPanel + rightPanel.setSizeIfNecessary(rightWidth, this.contentPane.height - 6) - val requestPanel = this.requestPanel - requestPanel.setSizeIfNecessary(rightWidth - 30, requestPanel.height) + val requestPanel = this.requestPanel + requestPanel.setSizeIfNecessary(rightWidth - 30, requestPanel.height) - this.responsePanel.let { - it.setSizeIfNecessary(rightWidth - 30, it.height) - it.bottomAlignTo(this.apisJList) - } + this.responsePanel.let { + it.setSizeIfNecessary(rightWidth - 30, it.height) + it.bottomAlignTo(this.apisJList) } } - } + }.throttle(50, TimeUnit.MILLISECONDS) //region api module private fun initApisModule() { diff --git a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/utils/CompensateRateLimiter.kt b/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/utils/CompensateRateLimiter.kt deleted file mode 100644 index ae2cb1ac..00000000 --- a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/utils/CompensateRateLimiter.kt +++ /dev/null @@ -1,91 +0,0 @@ -package com.itangcent.idea.plugin.utils - -import com.google.common.util.concurrent.RateLimiter -import com.itangcent.intellij.context.ActionContext -import java.util.concurrent.atomic.AtomicLong -import kotlin.math.ceil - -@Suppress("UnstableApiUsage") -class CompensateRateLimiter private constructor( - permitsPerSecond: Double, -) { - - private val rateLimiter = RateLimiter.create(permitsPerSecond) - - @Volatile - private var compensateStatus = 0 - - private val delayCompensate: Long = ceil(1000.0 / permitsPerSecond).toLong() - - private var lastAcquire = AtomicLong(0L) - - fun tryAcquire(action: () -> Unit) { - if (rateLimiter.tryAcquire()) { - execute(action) - } else { - lastAcquire.update() - tryCompensate(action) - } - } - - private fun execute(action: () -> Unit) { - action() - } - - private fun AtomicLong.update() { - val now = System.currentTimeMillis() - while (true) { - val curr = this.get() - if (curr >= now || this.compareAndSet(curr, now)) { - break - } - } - } - - private fun tryCompensate(action: () -> Unit) { - synchronized(this) { - if (compensateStatus == 1) { - return - } - compensateStatus = 1 - compensate(action) - } - } - - private fun compensate(action: () -> Unit) { - runAsync { - try { - while (true) { - rateLimiter.acquire() - execute(action) - var completed = false - synchronized(this) { - if (lastAcquire.get() + delayCompensate <= System.currentTimeMillis()) { - completed = true - } - } - if (completed) { - break - } - } - } finally { - compensateStatus = 0 - } - } - } - - private fun runAsync(action: () -> Unit) { - val context = ActionContext.getContext() - if (context != null) { - context.runAsync(action) - } else { - Thread(action).start() - } - } - - companion object { - fun create(permitsPerSecond: Number): CompensateRateLimiter { - return CompensateRateLimiter(permitsPerSecond.toDouble()) - } - } -} \ No newline at end of file diff --git a/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/utils/CompensateRateLimiterTest.kt b/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/utils/CompensateRateLimiterTest.kt deleted file mode 100644 index 3471f810..00000000 --- a/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/utils/CompensateRateLimiterTest.kt +++ /dev/null @@ -1,83 +0,0 @@ -package com.itangcent.idea.plugin.utils - -import com.itangcent.intellij.context.ActionContext -import org.junit.jupiter.api.Test -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicInteger -import java.util.concurrent.atomic.AtomicLong -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -/** - * Test case of [CompensateRateLimiter] - */ -internal class CompensateRateLimiterTest { - - @Test - fun tryAcquire() { - run { - val compensateRateLimiter = CompensateRateLimiter.create(2) - val last = AtomicLong(0L) - val times = AtomicInteger(0) - val start = System.currentTimeMillis() - for (i in 0..2) { - compensateRateLimiter.tryAcquire { - val now = System.currentTimeMillis() - do { - val l = last.get() - if (l >= now || last.compareAndSet(l, now)) { - break - } - } while (true) - times.incrementAndGet() - } - } - assertTrue { last.get() >= start } - assertEquals(1, times.get()) - val end = System.currentTimeMillis() - Thread.sleep(700) - assertEquals(2, times.get()) - assertTrue { last.get() >= end } - } - run { - val compensateRateLimiter = CompensateRateLimiter.create(2) - val last = AtomicLong(0L) - val times = AtomicInteger(0) - val start = System.currentTimeMillis() - val until = start + TimeUnit.SECONDS.toMillis(4) - val lastAcquire = AtomicLong(0L) - while (until > System.currentTimeMillis()) { - lastAcquire.set(System.currentTimeMillis()) - compensateRateLimiter.tryAcquire { - val now = System.currentTimeMillis() - println(now) - do { - val l = last.get() - if (l >= now || last.compareAndSet(l, now)) { - break - } - } while (true) - times.incrementAndGet() - } - Thread.sleep(100) - } - assertTrue { last.get() >= start } - times.get().let { - assertTrue { it >= 8 } - assertTrue { it <= 10 } - } - Thread.sleep(700) - assertTrue { last.get() >= lastAcquire.get() } - } - } - - @Test - fun tryAcquireWithContext() { - val actionContext = ActionContext.ActionContextBuilder() - .build() - actionContext.runAsync { - tryAcquire() - } - actionContext.waitComplete() - } -} \ No newline at end of file