@@ -5,6 +5,10 @@ import jupyter.kotlin.DependsOn
55import jupyter.kotlin.KotlinContext
66import jupyter.kotlin.KotlinKernelHostProvider
77import jupyter.kotlin.Repository
8+ import kotlinx.coroutines.Dispatchers
9+ import kotlinx.coroutines.GlobalScope
10+ import kotlinx.coroutines.launch
11+ import org.jetbrains.annotations.TestOnly
812import org.jetbrains.kotlin.config.KotlinCompilerVersion
913import org.jetbrains.kotlinx.jupyter.api.Code
1014import org.jetbrains.kotlinx.jupyter.api.ExecutionCallback
@@ -48,6 +52,7 @@ import org.jetbrains.kotlinx.jupyter.repl.CellExecutor
4852import org.jetbrains.kotlinx.jupyter.repl.CompletionResult
4953import org.jetbrains.kotlinx.jupyter.repl.ContextUpdater
5054import org.jetbrains.kotlinx.jupyter.repl.EvalResult
55+ import org.jetbrains.kotlinx.jupyter.repl.EvalResultEx
5156import org.jetbrains.kotlinx.jupyter.repl.InternalEvaluator
5257import org.jetbrains.kotlinx.jupyter.repl.KotlinCompleter
5358import org.jetbrains.kotlinx.jupyter.repl.ListErrorsResult
@@ -120,7 +125,8 @@ interface ReplForJupyter {
120125
121126 suspend fun serializeVariables (cellId : Int , descriptorsState : Map <String , SerializedVariablesState >, callback : (SerializationReply ) -> Unit )
122127
123- suspend fun serializeVariables (topLevelVarName : String , descriptorsState : Map <String , SerializedVariablesState >, callback : (SerializationReply ) -> Unit )
128+ suspend fun serializeVariables (topLevelVarName : String , descriptorsState : Map <String , SerializedVariablesState >, pathToDescriptor : List <String > = emptyList(),
129+ callback : (SerializationReply ) -> Unit )
124130
125131 val homeDir: File ?
126132
@@ -191,7 +197,7 @@ class ReplForJupyterImpl(
191197
192198 override val variablesSerializer = VariablesSerializer ()
193199
194- private val librariesScanner = LibrariesScanner (notebook)
200+ val librariesScanner = LibrariesScanner (notebook)
195201 private val resourcesProcessor = LibraryResourcesProcessorImpl ()
196202
197203 override var outputConfig
@@ -347,7 +353,7 @@ class ReplForJupyterImpl(
347353 )
348354
349355 private var evalContextEnabled = false
350- private fun withEvalContext (action : () -> EvalResult ): EvalResult {
356+ private fun < T > withEvalContext (action : () -> T ): T {
351357 return synchronized(this ) {
352358 evalContextEnabled = true
353359 try {
@@ -365,14 +371,14 @@ class ReplForJupyterImpl(
365371 else context.compilationConfiguration.asSuccess()
366372 }
367373
368- /* *
369- * Used for debug purposes.
370- * @see ReplCommand
371- */
374+ @TestOnly
375+ @Suppress(" unused" )
372376 private fun printVariables (isHtmlFormat : Boolean = false) = log.debug(
373377 if (isHtmlFormat) notebook.variablesReportAsHTML() else notebook.variablesReport()
374378 )
375379
380+ @TestOnly
381+ @Suppress(" unused" )
376382 private fun printUsagesInfo (cellId : Int , usedVariables : Set <String >? ) {
377383 log.debug(buildString {
378384 if (usedVariables == null || usedVariables.isEmpty()) {
@@ -386,7 +392,7 @@ class ReplForJupyterImpl(
386392 })
387393 }
388394
389- fun evalEx (code : Code , displayHandler : DisplayHandler ? , jupyterId : Int ): EvalResult {
395+ fun evalEx (code : Code , displayHandler : DisplayHandler ? , jupyterId : Int ): EvalResultEx {
390396 return withEvalContext {
391397 rethrowAsLibraryException(LibraryProblemPart .BEFORE_CELL_CALLBACKS ) {
392398 beforeCellExecution.forEach { executor.execute(it) }
@@ -426,8 +432,15 @@ class ReplForJupyterImpl(
426432 // printUsagesInfo(jupyterId, cellVariables[jupyterId - 1])
427433 val serializedData = variablesSerializer.serializeVariables(jupyterId - 1 , notebook.variablesState, notebook.unchangedVariables())
428434
429- EvalResult (
435+ GlobalScope .launch(Dispatchers .Default ) {
436+ variablesSerializer.tryValidateCache(jupyterId - 1 , notebook.cellVariables)
437+ }
438+
439+ EvalResultEx (
430440 result.result.value,
441+ rendered,
442+ result.scriptInstance,
443+ result.result.name,
431444 EvaluatedSnippetMetadata (newClasspath, compiledData, newImports, serializedData),
432445 )
433446 }
@@ -525,8 +538,9 @@ class ReplForJupyterImpl(
525538 doWithLock(SerializationArgs (descriptorsState, cellId = cellId, callback = callback), serializationQueue, SerializationReply (cellId, descriptorsState), ::doSerializeVariables)
526539 }
527540
528- override suspend fun serializeVariables (topLevelVarName : String , descriptorsState : Map <String , SerializedVariablesState >, callback : (SerializationReply ) -> Unit ) {
529- doWithLock(SerializationArgs (descriptorsState, topLevelVarName = topLevelVarName, callback = callback), serializationQueue, SerializationReply (), ::doSerializeVariables)
541+ override suspend fun serializeVariables (topLevelVarName : String , descriptorsState : Map <String , SerializedVariablesState >, pathToDescriptor : List <String >,
542+ callback : (SerializationReply ) -> Unit ) {
543+ doWithLock(SerializationArgs (descriptorsState, topLevelVarName = topLevelVarName, callback = callback, pathToDescriptor = pathToDescriptor), serializationQueue, SerializationReply (), ::doSerializeVariables)
530544 }
531545
532546 private fun doSerializeVariables (args : SerializationArgs ): SerializationReply {
@@ -537,7 +551,7 @@ class ReplForJupyterImpl(
537551 finalAns
538552 }
539553 args.descriptorsState.forEach { (name, state) ->
540- resultMap[name] = variablesSerializer.doIncrementalSerialization(cellId - 1 , name, state)
554+ resultMap[name] = variablesSerializer.doIncrementalSerialization(cellId - 1 , name, state, args.pathToDescriptor )
541555 }
542556 log.debug(" Serialization cellID: $cellId " )
543557 log.debug(" Serialization answer: ${resultMap.entries.first().value.fieldDescriptor} " )
@@ -581,6 +595,7 @@ class ReplForJupyterImpl(
581595 val descriptorsState : Map <String , SerializedVariablesState >,
582596 var cellId : Int = -1 ,
583597 val topLevelVarName : String = " " ,
598+ val pathToDescriptor : List <String > = emptyList(),
584599 override val callback : (SerializationReply ) -> Unit
585600 ) : LockQueueArgs<SerializationReply>
586601
0 commit comments