aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorIgnat Beresnev <ignat@beresnev.me>2022-02-14 10:48:38 +0300
committerGitHub <noreply@github.com>2022-02-14 10:48:38 +0300
commita43e11e08d57bd898efc72d6db94ed3d4b01f74f (patch)
tree5949ef8a2c26c5b65a64ad4b777081860deec6d9 /core
parent019cef47f1bf993a7a25ec73e88b1d9da25528eb (diff)
downloaddokka-a43e11e08d57bd898efc72d6db94ed3d4b01f74f.tar.gz
dokka-a43e11e08d57bd898efc72d6db94ed3d4b01f74f.tar.bz2
dokka-a43e11e08d57bd898efc72d6db94ed3d4b01f74f.zip
Shutdown coroutines dispatchers after each module pass (#2325)
* Update kotlinx.coroutines to 1.6.0 * Shutdown common coroutines dispatchers after each module pass * Don't finalize coroutines in unit tests Co-authored-by: Mikhail Zarechenskiy <mikhail.zarechenskiy@jetbrains.com>
Diffstat (limited to 'core')
-rw-r--r--core/api/core.api11
-rw-r--r--core/src/main/kotlin/DokkaGenerator.kt27
-rw-r--r--core/src/main/kotlin/configuration.kt19
-rw-r--r--core/src/main/kotlin/defaultConfiguration.kt1
-rw-r--r--core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt3
5 files changed, 33 insertions, 28 deletions
diff --git a/core/api/core.api b/core/api/core.api
index 53a0ab3f..6ce8ba84 100644
--- a/core/api/core.api
+++ b/core/api/core.api
@@ -65,6 +65,7 @@ public abstract interface class org/jetbrains/dokka/DokkaConfiguration : java/io
public abstract fun getCacheRoot ()Ljava/io/File;
public abstract fun getDelayTemplateSubstitution ()Z
public abstract fun getFailOnWarning ()Z
+ public abstract fun getFinalizeCoroutines ()Z
public abstract fun getIncludes ()Ljava/util/Set;
public abstract fun getModuleName ()Ljava/lang/String;
public abstract fun getModuleVersion ()Ljava/lang/String;
@@ -168,14 +169,15 @@ public abstract interface class org/jetbrains/dokka/DokkaConfigurationBuilder {
public final class org/jetbrains/dokka/DokkaConfigurationImpl : org/jetbrains/dokka/DokkaConfiguration {
public fun <init> ()V
- public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/io/File;ZLjava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZZLjava/util/Set;Z)V
- public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/io/File;ZLjava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZZLjava/util/Set;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/io/File;ZLjava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZZLjava/util/Set;ZZ)V
+ public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/io/File;ZLjava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZZLjava/util/Set;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String;
public final fun component10 ()Z
public final fun component11 ()Z
public final fun component12 ()Z
public final fun component13 ()Ljava/util/Set;
public final fun component14 ()Z
+ public final fun component15 ()Z
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/io/File;
public final fun component4 ()Ljava/io/File;
@@ -184,12 +186,13 @@ public final class org/jetbrains/dokka/DokkaConfigurationImpl : org/jetbrains/do
public final fun component7 ()Ljava/util/List;
public final fun component8 ()Ljava/util/List;
public final fun component9 ()Ljava/util/List;
- public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/io/File;ZLjava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZZLjava/util/Set;Z)Lorg/jetbrains/dokka/DokkaConfigurationImpl;
- public static synthetic fun copy$default (Lorg/jetbrains/dokka/DokkaConfigurationImpl;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/io/File;ZLjava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZZLjava/util/Set;ZILjava/lang/Object;)Lorg/jetbrains/dokka/DokkaConfigurationImpl;
+ public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/io/File;ZLjava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZZLjava/util/Set;ZZ)Lorg/jetbrains/dokka/DokkaConfigurationImpl;
+ public static synthetic fun copy$default (Lorg/jetbrains/dokka/DokkaConfigurationImpl;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/io/File;ZLjava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZZLjava/util/Set;ZZILjava/lang/Object;)Lorg/jetbrains/dokka/DokkaConfigurationImpl;
public fun equals (Ljava/lang/Object;)Z
public fun getCacheRoot ()Ljava/io/File;
public fun getDelayTemplateSubstitution ()Z
public fun getFailOnWarning ()Z
+ public fun getFinalizeCoroutines ()Z
public fun getIncludes ()Ljava/util/Set;
public fun getModuleName ()Ljava/lang/String;
public fun getModuleVersion ()Ljava/lang/String;
diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt
index 9241d728..a14775cb 100644
--- a/core/src/main/kotlin/DokkaGenerator.kt
+++ b/core/src/main/kotlin/DokkaGenerator.kt
@@ -2,15 +2,12 @@
package org.jetbrains.dokka
+import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.InternalCoroutinesApi
-import kotlinx.coroutines.scheduling.ExperimentalCoroutineDispatcher
import org.jetbrains.dokka.generation.GracefulGenerationExit
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.DokkaPlugin
import org.jetbrains.dokka.utilities.DokkaLogger
-import kotlin.reflect.full.memberProperties
-import kotlin.reflect.jvm.isAccessible
/**
* DokkaGenerator is the main entry point for generating documentation
@@ -45,28 +42,12 @@ class DokkaGenerator(
additionalPlugins: List<DokkaPlugin> = emptyList()
) = DokkaContext.create(configuration, logger, additionalPlugins)
+ @OptIn(DelicateCoroutinesApi::class)
private fun finalizeCoroutines() {
- runCatching {
- Dispatchers.Default.closeExecutor()
-
- Dispatchers.IO.let { dispatcher ->
- dispatcher::class.memberProperties.find {
- it.name == "dispatcher"
- }?.also {
- it.isAccessible = true
- }?.call(dispatcher)
- }?.closeExecutor()
+ if (configuration.finalizeCoroutines) {
+ Dispatchers.shutdown()
}
}
-
- @OptIn(InternalCoroutinesApi::class)
- private fun Any.closeExecutor() = (this as ExperimentalCoroutineDispatcher).also {
- it.executor::class.members
- .find { it.name == "close" }
- ?.also {
- it.isAccessible = true
- }?.call(it.executor)
- }
}
class Timer internal constructor(startTime: Long, private val logger: DokkaLogger?) {
diff --git a/core/src/main/kotlin/configuration.kt b/core/src/main/kotlin/configuration.kt
index 038a5bb7..ebd6ed61 100644
--- a/core/src/main/kotlin/configuration.kt
+++ b/core/src/main/kotlin/configuration.kt
@@ -134,6 +134,25 @@ interface DokkaConfiguration : Serializable {
val includes: Set<File>
val suppressInheritedMembers: Boolean
+ /**
+ * Whether coroutines dispatchers should be shutdown after
+ * generating documentation via [DokkaGenerator.generate].
+ *
+ * It effectively stops all background threads associated with
+ * coroutines in order to make classes unloadable by the JVM,
+ * and rejects all new tasks with [RejectedExecutionException]
+ *
+ * This is primarily useful for multi-module builds where coroutines
+ * can be shut down after each module's partial task to avoid
+ * possible memory leaks.
+ *
+ * However, this can lead to problems in specific lifecycles where
+ * coroutines are shared and will be reused after documentation generation,
+ * and closing it down will leave the build in an inoperable state.
+ * One such example is unit tests, for which finalization should be disabled.
+ */
+ val finalizeCoroutines: Boolean
+
enum class SerializationFormat : Serializable {
JSON, XML
}
diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt
index 4d23ce68..d4f92f33 100644
--- a/core/src/main/kotlin/defaultConfiguration.kt
+++ b/core/src/main/kotlin/defaultConfiguration.kt
@@ -19,6 +19,7 @@ data class DokkaConfigurationImpl(
override val suppressObviousFunctions: Boolean = DokkaDefaults.suppressObviousFunctions,
override val includes: Set<File> = emptySet(),
override val suppressInheritedMembers: Boolean = DokkaDefaults.suppressInheritedMembers,
+ override val finalizeCoroutines: Boolean = true,
) : DokkaConfiguration
data class PluginConfigurationImpl(
diff --git a/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt b/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt
index 804e02ce..623fcc2d 100644
--- a/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt
+++ b/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt
@@ -54,7 +54,8 @@ class TestDokkaConfigurationBuilder {
suppressObviousFunctions = suppressObviousFunctions,
includes = includes.toSet(),
suppressInheritedMembers = suppressInheritedMembers,
- delayTemplateSubstitution = delayTemplateSubstitution
+ delayTemplateSubstitution = delayTemplateSubstitution,
+ finalizeCoroutines = false
)
fun sourceSets(block: SourceSetsBuilder.() -> Unit) {