Offload legacy dependency resolver work to a separate thread pool
This is mainly to improve experience for kdsl users before gradle migrates to new API
This commit is contained in:
@@ -24,11 +24,13 @@ import kotlin.script.dependencies.Environment
|
|||||||
import kotlin.script.dependencies.ScriptDependencies
|
import kotlin.script.dependencies.ScriptDependencies
|
||||||
import kotlin.script.dependencies.ScriptReport
|
import kotlin.script.dependencies.ScriptReport
|
||||||
|
|
||||||
|
interface LegacyResolverWrapper
|
||||||
|
|
||||||
// NOTE: not implementing resolver wrapper since it was not implemented initially and this is deprecated API
|
// NOTE: not implementing resolver wrapper since it was not implemented initially and this is deprecated API
|
||||||
@Deprecated("Compatibility with deprecated API")
|
@Deprecated("Compatibility with deprecated API")
|
||||||
internal class LegacyPackageDependencyResolverWrapper(
|
internal class LegacyPackageDependencyResolverWrapper(
|
||||||
val legacyResolver: ScriptDependenciesResolver
|
val legacyResolver: ScriptDependenciesResolver
|
||||||
) : kotlin.script.dependencies.DependenciesResolver {
|
) : kotlin.script.dependencies.DependenciesResolver, LegacyResolverWrapper {
|
||||||
override fun resolve(
|
override fun resolve(
|
||||||
scriptContents: kotlin.script.dependencies.ScriptContents,
|
scriptContents: kotlin.script.dependencies.ScriptContents,
|
||||||
environment: Environment
|
environment: Environment
|
||||||
@@ -68,8 +70,9 @@ internal class LegacyPackageDependencyResolverWrapper(
|
|||||||
|
|
||||||
internal class ApiChangeDependencyResolverWrapper(
|
internal class ApiChangeDependencyResolverWrapper(
|
||||||
override val delegate: kotlin.script.dependencies.ScriptDependenciesResolver
|
override val delegate: kotlin.script.dependencies.ScriptDependenciesResolver
|
||||||
) : kotlin.script.dependencies.DependenciesResolver, DependencyResolverWrapper<kotlin.script.dependencies.ScriptDependenciesResolver> {
|
) : kotlin.script.dependencies.DependenciesResolver,
|
||||||
|
DependencyResolverWrapper<kotlin.script.dependencies.ScriptDependenciesResolver>,
|
||||||
|
LegacyResolverWrapper {
|
||||||
override fun resolve(
|
override fun resolve(
|
||||||
scriptContents: kotlin.script.dependencies.ScriptContents,
|
scriptContents: kotlin.script.dependencies.ScriptContents,
|
||||||
environment: Environment
|
environment: Environment
|
||||||
@@ -93,7 +96,7 @@ internal class ApiChangeDependencyResolverWrapper(
|
|||||||
return DependenciesResolver.ResolveResult.Success(dependencies, reports)
|
return DependenciesResolver.ResolveResult.Success(dependencies, reports)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.convertSeverity(): ScriptReport.Severity = when(this) {
|
private fun kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.convertSeverity(): ScriptReport.Severity = when (this) {
|
||||||
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.ERROR -> ScriptReport.Severity.ERROR
|
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.ERROR -> ScriptReport.Severity.ERROR
|
||||||
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.WARNING -> ScriptReport.Severity.WARNING
|
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.WARNING -> ScriptReport.Severity.WARNING
|
||||||
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.INFO -> ScriptReport.Severity.INFO
|
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.INFO -> ScriptReport.Severity.INFO
|
||||||
|
|||||||
+40
-17
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
|||||||
import org.jetbrains.kotlin.script.*
|
import org.jetbrains.kotlin.script.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
import kotlin.script.dependencies.DependenciesResolver
|
||||||
import kotlin.script.dependencies.ScriptDependencies
|
import kotlin.script.dependencies.ScriptDependencies
|
||||||
import kotlin.script.dependencies.experimental.AsyncDependenciesResolver
|
import kotlin.script.dependencies.experimental.AsyncDependenciesResolver
|
||||||
|
|
||||||
@@ -44,8 +45,12 @@ internal class ScriptDependenciesUpdater(
|
|||||||
private val scriptDefinitionProvider: KotlinScriptDefinitionProvider
|
private val scriptDefinitionProvider: KotlinScriptDefinitionProvider
|
||||||
) {
|
) {
|
||||||
private val requests = ConcurrentHashMap<String, ModStampedRequest>()
|
private val requests = ConcurrentHashMap<String, ModStampedRequest>()
|
||||||
private val scriptDependencyUpdatesDispatcher = Executors.newFixedThreadPool(1).asCoroutineDispatcher()
|
|
||||||
private val contentLoader = ScriptContentLoader(project)
|
private val contentLoader = ScriptContentLoader(project)
|
||||||
|
private val asyncUpdatesDispatcher = Executors.newFixedThreadPool(1).asCoroutineDispatcher()
|
||||||
|
private val legacyUpdatesDispatcher =
|
||||||
|
Executors.newFixedThreadPool(
|
||||||
|
(Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
|
||||||
|
).asCoroutineDispatcher()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
listenToVfsChanges()
|
listenToVfsChanges()
|
||||||
@@ -93,7 +98,7 @@ internal class ScriptDependenciesUpdater(
|
|||||||
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) ?: return false
|
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) ?: return false
|
||||||
|
|
||||||
return when (scriptDef.dependencyResolver) {
|
return when (scriptDef.dependencyResolver) {
|
||||||
is AsyncDependenciesResolver -> {
|
is AsyncDependenciesResolver, is LegacyResolverWrapper -> {
|
||||||
updateAsync(file, scriptDef)
|
updateAsync(file, scriptDef)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -134,26 +139,44 @@ internal class ScriptDependenciesUpdater(
|
|||||||
scriptDef: KotlinScriptDefinition
|
scriptDef: KotlinScriptDefinition
|
||||||
): TimeStampedJob {
|
): TimeStampedJob {
|
||||||
val currentTimeStamp = TimeStamps.next()
|
val currentTimeStamp = TimeStamps.next()
|
||||||
val dependenciesResolver = scriptDef.dependencyResolver as AsyncDependenciesResolver
|
val dependenciesResolver = scriptDef.dependencyResolver
|
||||||
val path = file.path
|
val newJob = if (dependenciesResolver is AsyncDependenciesResolver) {
|
||||||
|
launch(asyncUpdatesDispatcher) {
|
||||||
val newJob = launch(scriptDependencyUpdatesDispatcher) {
|
processResult(
|
||||||
val result = dependenciesResolver.resolveAsync(
|
file, currentTimeStamp,
|
||||||
contentLoader.getScriptContents(scriptDef, file),
|
dependenciesResolver.resolveAsync(
|
||||||
contentLoader.getEnvironment(scriptDef)
|
contentLoader.getScriptContents(scriptDef, file),
|
||||||
)
|
contentLoader.getEnvironment(scriptDef)
|
||||||
val lastTimeStamp = requests[path]?.job?.timeStamp
|
)
|
||||||
val isLastSentRequest = lastTimeStamp == null || lastTimeStamp == currentTimeStamp
|
)
|
||||||
if (isLastSentRequest) {
|
}
|
||||||
ServiceManager.getService(project, ScriptReportSink::class.java)?.attachReports(file, result.reports)
|
}
|
||||||
if (cache(result.dependencies ?: ScriptDependencies.Empty, file)) {
|
else {
|
||||||
onChange()
|
assert(dependenciesResolver is LegacyResolverWrapper)
|
||||||
}
|
launch(legacyUpdatesDispatcher) {
|
||||||
|
processResult(
|
||||||
|
file, currentTimeStamp,
|
||||||
|
dependenciesResolver.resolve(
|
||||||
|
contentLoader.getScriptContents(scriptDef, file),
|
||||||
|
contentLoader.getEnvironment(scriptDef)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TimeStampedJob(newJob, currentTimeStamp)
|
return TimeStampedJob(newJob, currentTimeStamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun processResult(file: VirtualFile, currentTimeStamp: TimeStamp, result: DependenciesResolver.ResolveResult) {
|
||||||
|
val lastTimeStamp = requests[file.path]?.job?.timeStamp
|
||||||
|
val isLastSentRequest = lastTimeStamp == null || lastTimeStamp == currentTimeStamp
|
||||||
|
if (isLastSentRequest) {
|
||||||
|
ServiceManager.getService(project, ScriptReportSink::class.java)?.attachReports(file, result.reports)
|
||||||
|
if (cache(result.dependencies ?: ScriptDependencies.Empty, file)) {
|
||||||
|
onChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun updateSync(file: VirtualFile, scriptDef: KotlinScriptDefinition): Boolean {
|
fun updateSync(file: VirtualFile, scriptDef: KotlinScriptDefinition): Boolean {
|
||||||
val newDeps = contentLoader.loadContentsAndResolveDependencies(scriptDef, file) ?: ScriptDependencies.Empty
|
val newDeps = contentLoader.loadContentsAndResolveDependencies(scriptDef, file) ?: ScriptDependencies.Empty
|
||||||
return cache(newDeps, file)
|
return cache(newDeps, file)
|
||||||
|
|||||||
Reference in New Issue
Block a user