do not use Dispatchers.IO without a reason, it may lead to the overuse of CPU and makes things just worse (part 2)

GitOrigin-RevId: dd424d2236a2f40bfd62fdda18a5e5be848732cc
This commit is contained in:
Vladimir Krivosheev
2024-08-22 17:21:52 +02:00
committed by intellij-monorepo-bot
parent dd6f51fbdd
commit fd5dd7e618
8 changed files with 31 additions and 20 deletions

View File

@@ -13,6 +13,7 @@ import kotlinx.coroutines.channels.ClosedSendChannelException
import kotlinx.coroutines.channels.toList
import org.jetbrains.annotations.ApiStatus.Obsolete
import org.jetbrains.intellij.build.telemetry.TraceManager.spanBuilder
import org.jetbrains.intellij.build.telemetry.use
import org.jetbrains.intellij.build.telemetry.useWithScope
import java.io.File
import java.io.InputStream
@@ -49,7 +50,7 @@ suspend fun runJava(mainClass: String,
.setAttribute(AttributeKey.stringArrayKey("jvmArgs"), jvmArgs)
.setAttribute("workingDir", "$workingDir")
.setAttribute("timeoutMillis", "$timeout")
.useWithScope(Dispatchers.IO) { span ->
.use(Dispatchers.IO) { span ->
val toDelete = ArrayList<Path>(3)
var process: Process? = null
try {

View File

@@ -6,15 +6,16 @@ import io.opentelemetry.api.trace.SpanBuilder
import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.serialization.Serializable
import org.jetbrains.intellij.build.io.DEFAULT_TIMEOUT
import org.jetbrains.intellij.build.productRunner.IntellijProductRunner
import org.jetbrains.intellij.build.telemetry.useWithScope
import org.jetbrains.intellij.build.telemetry.use
import org.jetbrains.jps.model.module.JpsModule
import java.nio.file.Files
import java.nio.file.Path
import java.util.concurrent.CancellationException
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.time.Duration
interface BuildContext : CompilationContext {
@@ -160,9 +161,10 @@ interface BuildContext : CompilationContext {
suspend inline fun <T> BuildContext.executeStep(
spanBuilder: SpanBuilder,
stepId: String,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
crossinline step: suspend CoroutineScope.(Span) -> T,
): T? {
return spanBuilder.useWithScope(Dispatchers.IO) { span ->
return spanBuilder.use(coroutineContext) { span ->
try {
options.buildStepListener.onStart(stepId, messages)
if (isStepSkipped(stepId)) {

View File

@@ -238,7 +238,6 @@ internal class DistributionForOsTaskResult(
private suspend fun buildOsSpecificDistributions(context: BuildContext): List<DistributionForOsTaskResult> {
return context.executeStep(spanBuilder("build OS-specific distributions"), BuildOptions.OS_SPECIFIC_DISTRIBUTIONS_STEP) {
setLastModifiedTime(context.paths.distAllDir, context)
if (context.isMacCodeSignEnabled) {
@@ -445,7 +444,7 @@ private suspend fun buildProjectArtifacts(platform: PlatformLayout, enabledPlugi
compilationTasks.buildProjectArtifacts(artifactNames)
}
suspend fun buildDistributions(context: BuildContext): Unit = spanBuilder("build distributions").useWithScope {
suspend fun buildDistributions(context: BuildContext): Unit = spanBuilder("build distributions").use {
context.checkDistributionBuildNumber()
checkProductProperties(context as BuildContextImpl)
copyDependenciesFile(context)
@@ -473,7 +472,7 @@ suspend fun buildDistributions(context: BuildContext): Unit = spanBuilder("build
return@coroutineScope
}
val contentReport = spanBuilder("build platform and plugin JARs").useWithScope {
val contentReport = spanBuilder("build platform and plugin JARs").use {
val contentReport = buildDistribution(state = distributionState, context)
if (context.productProperties.buildSourcesArchive) {
buildSourcesArchive(contentReport, context)

View File

@@ -478,7 +478,7 @@ private suspend fun validatePlugins(context: BuildContext, pluginSpecs: Collecti
continue
}
launch {
validatePlugin(path, context, span)
validatePlugin(path = path, context = context, span = span)
}
}
}
@@ -1255,7 +1255,7 @@ private suspend fun archivePlugins(items: Collection<NonBundledPlugin>, compress
.setAttribute("input", source.toString())
.setAttribute("outputFile", target.toString())
.setAttribute("optimizedZip", optimized)
.useWithScope {
.use {
archivePlugin(optimized = optimized, target = target, compress = compress, source = source, context = context)
}
if (withBlockMap) {

View File

@@ -83,7 +83,7 @@ class LinuxDistributionBuilder(
updateExecutablePermissions(osAndArchSpecificDistPath, executableFileMatchers)
context.executeStep(spanBuilder("Build Linux artifacts").setAttribute("arch", arch.name), BuildOptions.LINUX_ARTIFACTS_STEP) {
if (customizer.buildArtifactWithoutRuntime) {
launch {
launch(Dispatchers.IO) {
context.executeStep(
spanBuilder("Build Linux .tar.gz without bundled Runtime")
.setAttribute("arch", arch.name)
@@ -110,7 +110,7 @@ class LinuxDistributionBuilder(
) { _ ->
buildTarGz(arch, runtimeDir, osAndArchSpecificDistPath, suffix(arch))
}
launch {
launch(Dispatchers.IO) {
if (arch == JvmArchitecture.x64) {
buildSnapPackage(runtimeDir, osAndArchSpecificDistPath, arch)
}
@@ -121,7 +121,7 @@ class LinuxDistributionBuilder(
}
if (tarGzPath != null ) {
context.executeStep(spanBuilder("bundle repair utility"), BuildOptions.REPAIR_UTILITY_BUNDLE_STEP) {
context.executeStep(spanBuilder("bundle repair utility"), BuildOptions.REPAIR_UTILITY_BUNDLE_STEP, Dispatchers.IO) {
val tempTar = Files.createTempDirectory(context.paths.tempDir, "tar-")
try {
unTar(tarGzPath, tempTar)
@@ -183,7 +183,7 @@ class LinuxDistributionBuilder(
spanBuilder("build Linux tar.gz")
.setAttribute("runtimeDir", runtimeDir?.toString() ?: "")
.useWithScope {
.use(Dispatchers.IO) {
val executableFileMatchers = generateExecutableFilesMatchers(includeRuntime = runtimeDir != null, arch).keys
tar(tarPath, tarRoot, dirs, executableFileMatchers, context.options.buildDateInSeconds)
checkInArchive(tarPath, tarRoot, context)

View File

@@ -45,7 +45,10 @@ class RepairUtilityBuilder {
suspend fun bundle(context: BuildContext, os: OsFamily, arch: JvmArchitecture, distributionDir: Path) {
context.executeStep(spanBuilder("bundle repair-utility").setAttribute("os", os.osName), REPAIR_UTILITY_BUNDLE_STEP) {
if (!canBinariesBeBuilt(context)) return@executeStep
if (!canBinariesBeBuilt(context)) {
return@executeStep
}
val cache = getBinaryCache(context).await()
val binary = findBinary(os, arch)
val path = cache.get(binary)

View File

@@ -4,8 +4,9 @@
package org.jetbrains.intellij.build
import io.opentelemetry.api.common.AttributeKey
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
@@ -72,7 +73,7 @@ internal suspend fun buildSearchableOptions(
// bundled maven is also downloaded during traverseUI execution in an external process,
// making it fragile to call more than one traverseUI at the same time (in the reproducibility test, for example),
// so it's pre-downloaded with proper synchronization
coroutineScope {
withContext(Dispatchers.IO) {
launch {
BundledMavenDownloader.downloadMaven4Libs(context.paths.communityHomeDirRoot)
}

View File

@@ -1,11 +1,13 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.intellij.build.pycharm
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.intellij.build.BuildContext
import org.jetbrains.intellij.build.FileSet
import org.jetbrains.intellij.build.telemetry.TraceManager
import org.jetbrains.intellij.build.dependencies.TeamCityHelper
import org.jetbrains.intellij.build.executeStep
import org.jetbrains.intellij.build.telemetry.TraceManager
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.div
@@ -13,6 +15,7 @@ import kotlin.io.path.div
object PyCharmBuildUtils {
const val SKELETONS_COPY_STEP = "skeletons_copy"
@JvmStatic
suspend fun copySkeletons(context: BuildContext, targetDirectory: Path, mask: String) {
context.executeStep(TraceManager.spanBuilder("copying skeletons"), SKELETONS_COPY_STEP) {
@@ -22,9 +25,11 @@ object PyCharmBuildUtils {
return@executeStep
}
FileSet(skeletonsDir)
.include(mask)
.copyToDir(targetDirectory / "skeletons")
withContext(Dispatchers.IO) {
FileSet(skeletonsDir)
.include(mask)
.copyToDir(targetDirectory / "skeletons")
}
}
}
}