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.ScriptReport
|
||||
|
||||
interface LegacyResolverWrapper
|
||||
|
||||
// NOTE: not implementing resolver wrapper since it was not implemented initially and this is deprecated API
|
||||
@Deprecated("Compatibility with deprecated API")
|
||||
internal class LegacyPackageDependencyResolverWrapper(
|
||||
val legacyResolver: ScriptDependenciesResolver
|
||||
) : kotlin.script.dependencies.DependenciesResolver {
|
||||
) : kotlin.script.dependencies.DependenciesResolver, LegacyResolverWrapper {
|
||||
override fun resolve(
|
||||
scriptContents: kotlin.script.dependencies.ScriptContents,
|
||||
environment: Environment
|
||||
@@ -68,8 +70,9 @@ internal class LegacyPackageDependencyResolverWrapper(
|
||||
|
||||
internal class ApiChangeDependencyResolverWrapper(
|
||||
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(
|
||||
scriptContents: kotlin.script.dependencies.ScriptContents,
|
||||
environment: Environment
|
||||
@@ -93,7 +96,7 @@ internal class ApiChangeDependencyResolverWrapper(
|
||||
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.WARNING -> ScriptReport.Severity.WARNING
|
||||
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 java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.script.dependencies.DependenciesResolver
|
||||
import kotlin.script.dependencies.ScriptDependencies
|
||||
import kotlin.script.dependencies.experimental.AsyncDependenciesResolver
|
||||
|
||||
@@ -44,8 +45,12 @@ internal class ScriptDependenciesUpdater(
|
||||
private val scriptDefinitionProvider: KotlinScriptDefinitionProvider
|
||||
) {
|
||||
private val requests = ConcurrentHashMap<String, ModStampedRequest>()
|
||||
private val scriptDependencyUpdatesDispatcher = Executors.newFixedThreadPool(1).asCoroutineDispatcher()
|
||||
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 {
|
||||
listenToVfsChanges()
|
||||
@@ -93,7 +98,7 @@ internal class ScriptDependenciesUpdater(
|
||||
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) ?: return false
|
||||
|
||||
return when (scriptDef.dependencyResolver) {
|
||||
is AsyncDependenciesResolver -> {
|
||||
is AsyncDependenciesResolver, is LegacyResolverWrapper -> {
|
||||
updateAsync(file, scriptDef)
|
||||
return false
|
||||
}
|
||||
@@ -134,26 +139,44 @@ internal class ScriptDependenciesUpdater(
|
||||
scriptDef: KotlinScriptDefinition
|
||||
): TimeStampedJob {
|
||||
val currentTimeStamp = TimeStamps.next()
|
||||
val dependenciesResolver = scriptDef.dependencyResolver as AsyncDependenciesResolver
|
||||
val path = file.path
|
||||
|
||||
val newJob = launch(scriptDependencyUpdatesDispatcher) {
|
||||
val result = dependenciesResolver.resolveAsync(
|
||||
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)) {
|
||||
onChange()
|
||||
}
|
||||
val dependenciesResolver = scriptDef.dependencyResolver
|
||||
val newJob = if (dependenciesResolver is AsyncDependenciesResolver) {
|
||||
launch(asyncUpdatesDispatcher) {
|
||||
processResult(
|
||||
file, currentTimeStamp,
|
||||
dependenciesResolver.resolveAsync(
|
||||
contentLoader.getScriptContents(scriptDef, file),
|
||||
contentLoader.getEnvironment(scriptDef)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(dependenciesResolver is LegacyResolverWrapper)
|
||||
launch(legacyUpdatesDispatcher) {
|
||||
processResult(
|
||||
file, currentTimeStamp,
|
||||
dependenciesResolver.resolve(
|
||||
contentLoader.getScriptContents(scriptDef, file),
|
||||
contentLoader.getEnvironment(scriptDef)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
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 {
|
||||
val newDeps = contentLoader.loadContentsAndResolveDependencies(scriptDef, file) ?: ScriptDependencies.Empty
|
||||
return cache(newDeps, file)
|
||||
|
||||
Reference in New Issue
Block a user