[threading] IJPL-234550: Add helper debug actions for loading the IDE with frequent non-cancellable locking actions

GitOrigin-RevId: 42ab7c7b5e383d8b7ce4d510107187f3a289ebe0
This commit is contained in:
Konstantin Nisht
2026-02-11 17:52:56 +01:00
committed by intellij-monorepo-bot
parent 9989be9f37
commit cc106510d7
4 changed files with 140 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.internal
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.ex.CheckboxAction
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.ui.Messages
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.jetbrains.annotations.ApiStatus
import kotlin.coroutines.cancellation.CancellationException
@ApiStatus.Internal
class FrequentBackgroundReadAction: CheckboxAction() {
companion object {
@Volatile
private var runningJob: Job? = null
@Volatile
private var sleepDurationMs: Long = 10
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}
override fun isSelected(e: AnActionEvent): Boolean {
return runningJob?.isActive == true
}
override fun setSelected(e: AnActionEvent, state: Boolean) {
if (state) {
// Show input dialog to get sleep duration
val input = Messages.showInputDialog(
e.project,
"Enter sleep duration in milliseconds:",
"Frequent Background Read Action",
null,
sleepDurationMs.toString(),
null
)
if (input.isNullOrBlank()) {
return // User cancelled
}
val duration = input.toLongOrNull()
if (duration == null || duration < 0) {
Messages.showErrorDialog(
e.project,
"Invalid duration. Please enter a positive number.",
"Invalid Input"
)
return
}
sleepDurationMs = duration
// Toggle ON: Start repeated background read actions
runningJob = e.coroutineScope.launch(Dispatchers.Default) {
try {
while (isActive) {
runReadAction {
Thread.sleep(sleepDurationMs)
}
delay(1)
}
} catch (e: CancellationException) {
// Expected on toggle OFF
throw e
}
}
} else {
// Toggle OFF: Cancel the running job
runningJob?.cancel()
runningJob = null
}
}
}

View File

@@ -0,0 +1,53 @@
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.internal
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.ex.CheckboxAction
import com.intellij.openapi.application.backgroundWriteAction
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.jetbrains.annotations.ApiStatus
import kotlin.coroutines.cancellation.CancellationException
@ApiStatus.Internal
class FrequentBackgroundWriteAction: CheckboxAction() {
companion object {
@Volatile
private var runningJob: Job? = null
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}
override fun isSelected(e: AnActionEvent): Boolean {
return runningJob?.isActive == true
}
override fun setSelected(e: AnActionEvent, state: Boolean) {
if (state) {
// Toggle ON: Start repeated background write actions
runningJob = e.coroutineScope.launch(Dispatchers.Default) {
try {
while (coroutineContext.isActive) {
backgroundWriteAction {
Thread.sleep(1)
}
delay(1)
}
} catch (e: CancellationException) {
// Expected on toggle OFF
throw e
}
}
} else {
// Toggle OFF: Cancel the running job
runningJob?.cancel()
runningJob = null
}
}
}

View File

@@ -2285,6 +2285,8 @@ action.EnableWayland.text=Native Wayland Support
action.RulerGuide.text=Ruler Guide
action.WriteActionUnderProgress.text=Test Write Action Under Progress
action.LongBackgroundWriteAction.text=Run Long Background Write Action
action.FrequentBackgroundWriteAction.text=Run Frequent Background Write Action
action.FrequentBackgroundReadAction.text=Run Frequent Background Read Action
action.TestProgressWindow.text=Test Progress Window
action.TestCoroutineProgress.text=Test Coroutine Progress
action.TestGestureAction.text=Test Gesture Action

View File

@@ -1512,6 +1512,8 @@
<action id="AddManyTestProcesses" internal="true" class="com.intellij.openapi.wm.impl.status.AddManyTestProcesses"/>
<action id="WriteActionUnderProgress" internal="true" class="com.intellij.internal.TestWriteActionUnderProgress"/>
<action id="LongBackgroundWriteAction" internal="true" class="com.intellij.internal.LongBackgroundWriteAction"/>
<action id="FrequentBackgroundWriteAction" internal="true" class="com.intellij.internal.FrequentBackgroundWriteAction"/>
<action id="FrequentBackgroundReadAction" internal="true" class="com.intellij.internal.FrequentBackgroundReadAction"/>
<action id="TestProgressWindow" internal="true" class="com.intellij.internal.TestProgressWindow"/>
<action id="TestCoroutineProgress" internal="true" class="com.intellij.internal.TestCoroutineProgressAction"/>
<separator/>