diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/CommunityLibraryLicenses.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/CommunityLibraryLicenses.kt
index cf7cccf0e08d..9a2b79330603 100644
--- a/platform/build-scripts/src/org/jetbrains/intellij/build/CommunityLibraryLicenses.kt
+++ b/platform/build-scripts/src/org/jetbrains/intellij/build/CommunityLibraryLicenses.kt
@@ -1224,6 +1224,9 @@ object CommunityLibraryLicenses {
jetbrainsLibrary("find-classes-model-experimental"),
jetbrainsLibrary("find-file-model"),
jetbrainsLibrary("find-file-model-experimental"),
+ jetbrainsLibrary("jetbrains.fleet.kernel"),
+ jetbrainsLibrary("jetbrains.fleet.rpc"),
+ jetbrainsLibrary("jetbrains.fleet.rpc.server"),
jetbrainsLibrary("git-learning-project"),
jetbrainsLibrary("intellij.remoterobot.remote.fixtures"),
jetbrainsLibrary("intellij.remoterobot.robot.server.core"),
diff --git a/platform/core-api/src/com/intellij/fleet/rpc/FleetRpc.kt b/platform/core-api/src/com/intellij/fleet/rpc/FleetRpc.kt
deleted file mode 100644
index 0f7a8ff1e327..000000000000
--- a/platform/core-api/src/com/intellij/fleet/rpc/FleetRpc.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.fleet.rpc
-
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.client.ClientAppSession
-import com.intellij.openapi.client.currentSession
-import com.intellij.openapi.components.service
-import fleet.rpc.core.FleetTransportFactory
-import org.jetbrains.annotations.ApiStatus
-
-@ApiStatus.Internal
-@ApiStatus.Experimental
-interface FleetRpc {
- companion object {
- fun getInstance(session: ClientAppSession): FleetRpc = session.service()
- fun getCurrentInstance(): FleetRpc = ApplicationManager.getApplication().currentSession.service()
- }
-
- fun getTransportFactory(): FleetTransportFactory
-}
-
-
diff --git a/platform/kernel/backend/intellij.platform.kernel.backend.iml b/platform/kernel/backend/intellij.platform.kernel.backend.iml
new file mode 100644
index 000000000000..69ba99de14f3
--- /dev/null
+++ b/platform/kernel/backend/intellij.platform.kernel.backend.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/platform/kernel/backend/resources/intellij.platform.kernel.backend.xml b/platform/kernel/backend/resources/intellij.platform.kernel.backend.xml
new file mode 100644
index 000000000000..119c0b16fd39
--- /dev/null
+++ b/platform/kernel/backend/resources/intellij.platform.kernel.backend.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/kernel/backend/src/RemoteApiProvider.kt b/platform/kernel/backend/src/RemoteApiProvider.kt
new file mode 100644
index 000000000000..ec92812f8279
--- /dev/null
+++ b/platform/kernel/backend/src/RemoteApiProvider.kt
@@ -0,0 +1,18 @@
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.platform.kernel.backend
+
+import com.intellij.openapi.extensions.ExtensionPointName
+import fleet.rpc.RemoteApi
+import org.jetbrains.annotations.ApiStatus
+import kotlin.reflect.KClass
+
+interface RemoteApiProvider {
+ data class RemoteApiDescriptor>(val klass: KClass, val service: () -> T)
+
+ fun getApis(): List>
+
+ companion object {
+ @ApiStatus.Internal
+ val EP_NAME = ExtensionPointName("com.intellij.platform.kernel.backend.remoteApiProvider")
+ }
+}
\ No newline at end of file
diff --git a/platform/kernel/backend/src/RemoteApiRegistry.kt b/platform/kernel/backend/src/RemoteApiRegistry.kt
new file mode 100644
index 000000000000..75c056ddc415
--- /dev/null
+++ b/platform/kernel/backend/src/RemoteApiRegistry.kt
@@ -0,0 +1,56 @@
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.platform.kernel.backend
+
+import com.intellij.openapi.extensions.ExtensionPointListener
+import com.intellij.openapi.extensions.PluginDescriptor
+import com.intellij.platform.kernel.backend.RemoteApiProvider.Companion.EP_NAME
+import com.intellij.platform.kernel.rpc.RemoteApiProviderService
+import com.intellij.util.containers.ContainerUtil
+import fleet.rpc.RemoteApi
+import fleet.rpc.core.InstanceId
+import kotlinx.coroutines.CoroutineScope
+import java.util.concurrent.ConcurrentHashMap
+import kotlin.collections.set
+import kotlin.reflect.KClass
+
+class RemoteApiRegistry(private val coroutineScope: CoroutineScope) : RemoteApiProviderService {
+ private val remoteApis = ConcurrentHashMap>, RemoteApi>>()
+ private val visitedEPs = ContainerUtil.createConcurrentWeakKeyWeakValueMap()
+
+ init {
+ EP_NAME.addExtensionPointListener(coroutineScope, object : ExtensionPointListener {
+ override fun extensionAdded(extension: RemoteApiProvider, pluginDescriptor: PluginDescriptor) {
+ if (visitedEPs.putIfAbsent(extension, Unit) == null) {
+ val apis = extension.getApis()
+ for (api in apis) {
+ remoteApis[api.klass.toInstanceId] = api.klass to api.service()
+ }
+ }
+ }
+
+ override fun extensionRemoved(extension: RemoteApiProvider, pluginDescriptor: PluginDescriptor) {
+ visitedEPs.remove(extension)
+ val apis = extension.getApis()
+ synchronized(this) {
+ apis.forEach { api ->
+ remoteApis.remove(api.klass.toInstanceId)
+ }
+ }
+ }
+ })
+ EP_NAME.extensions.filter { visitedEPs.putIfAbsent(it, Unit) == null }.flatMap { it.getApis() }.forEach { api ->
+ remoteApis[api.klass.toInstanceId] = api.klass to api.service()
+ }
+ }
+
+ override fun > resolve(kclass: KClass): T {
+ return remoteApis[kclass.toInstanceId]?.second as? T ?: throw IllegalStateException("No remote API found for $kclass")
+ }
+
+ fun resolve(instanceId: InstanceId): Pair>, RemoteApi> {
+ return remoteApis[instanceId] ?: throw IllegalStateException("No remote API found for $instanceId")
+ }
+}
+
+private val KClass>.toInstanceId: InstanceId
+ get() = InstanceId(this.qualifiedName!!)
diff --git a/platform/kernel/monolith/intellij.platform.kernel.monolith.iml b/platform/kernel/monolith/intellij.platform.kernel.monolith.iml
new file mode 100644
index 000000000000..de5859c3d5e7
--- /dev/null
+++ b/platform/kernel/monolith/intellij.platform.kernel.monolith.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/platform/kernel/monolith/resources/intellij.platform.kernel.monolith.xml b/platform/kernel/monolith/resources/intellij.platform.kernel.monolith.xml
new file mode 100644
index 000000000000..7d98f628cee6
--- /dev/null
+++ b/platform/kernel/monolith/resources/intellij.platform.kernel.monolith.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/kernel/monolith/src/MonolithKernelService.kt b/platform/kernel/monolith/src/MonolithKernelService.kt
new file mode 100644
index 000000000000..7bd915fce5ef
--- /dev/null
+++ b/platform/kernel/monolith/src/MonolithKernelService.kt
@@ -0,0 +1,35 @@
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.platform.kernel.monolith
+
+import com.intellij.platform.kernel.KernelService
+import com.intellij.platform.kernel.util.CommonInstructionSet
+import com.intellij.platform.kernel.util.KernelRpcSerialization
+import com.intellij.platform.kernel.util.ReadTracker
+import com.intellij.platform.kernel.util.withKernel
+import fleet.kernel.Kernel
+import fleet.kernel.kernel
+import fleet.kernel.rebase.LeaderKernelMiddleware
+import fleet.kernel.rebase.encoder
+import fleet.kernel.rete.Rete
+import kotlinx.coroutines.*
+
+internal class MonolithKernelService(coroutineScope: CoroutineScope) : KernelService {
+ override val kernel: Kernel
+ override val rete: Rete
+
+ init {
+ val kernelDeferred: CompletableDeferred = CompletableDeferred()
+ val reteDeferred : CompletableDeferred = CompletableDeferred()
+
+ coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {
+ withKernel(middleware = LeaderKernelMiddleware(KernelRpcSerialization, CommonInstructionSet.encoder())) {
+ kernelDeferred.complete(kernel())
+ reteDeferred.complete(currentCoroutineContext()[Rete]!!)
+ ReadTracker.subscribeForChanges()
+ }
+ }
+ kernel = kernelDeferred.getCompleted()
+ rete = reteDeferred.getCompleted()
+ }
+}
+
diff --git a/platform/kernel/shared/intellij.platform.kernel.iml b/platform/kernel/shared/intellij.platform.kernel.iml
new file mode 100644
index 000000000000..d9765246bab4
--- /dev/null
+++ b/platform/kernel/shared/intellij.platform.kernel.iml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar
+ $MAVEN_REPOSITORY$/jetbrains/fleet/rhizomedb-compiler-plugin/1.9.20-0.17/rhizomedb-compiler-plugin-1.9.20-0.17.jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/platform/kernel/shared/resources/META-INF/services/fleet.util.logging.KLoggerFactory b/platform/kernel/shared/resources/META-INF/services/fleet.util.logging.KLoggerFactory
new file mode 100644
index 000000000000..6984072c157b
--- /dev/null
+++ b/platform/kernel/shared/resources/META-INF/services/fleet.util.logging.KLoggerFactory
@@ -0,0 +1 @@
+com.intellij.platform.kernel.util.IjLoggerFactory
\ No newline at end of file
diff --git a/platform/kernel/shared/resources/intellij.platform.kernel.xml b/platform/kernel/shared/resources/intellij.platform.kernel.xml
new file mode 100644
index 000000000000..0bb1f9b01c4b
--- /dev/null
+++ b/platform/kernel/shared/resources/intellij.platform.kernel.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/platform/core-api/src/com/intellij/fleet/kernel/KernelService.kt b/platform/kernel/shared/src/KernelService.kt
similarity index 71%
rename from platform/core-api/src/com/intellij/fleet/kernel/KernelService.kt
rename to platform/kernel/shared/src/KernelService.kt
index 76e70a2df270..875b164561c6 100644
--- a/platform/core-api/src/com/intellij/fleet/kernel/KernelService.kt
+++ b/platform/kernel/shared/src/KernelService.kt
@@ -1,5 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.fleet.kernel
+package com.intellij.platform.kernel
import com.intellij.openapi.application.ApplicationManager
import fleet.kernel.DbSource
@@ -7,10 +7,8 @@ import fleet.kernel.Kernel
import fleet.kernel.rete.Rete
import fleet.kernel.withCondition
import kotlinx.coroutines.*
-import org.jetbrains.annotations.ApiStatus
+import kotlin.coroutines.CoroutineContext
-@ApiStatus.Internal
-@ApiStatus.Experimental
interface KernelService {
val kernel: Kernel
val rete: Rete
@@ -18,9 +16,11 @@ interface KernelService {
val instance: KernelService
get() = ApplicationManager.getApplication().getService(KernelService::class.java)
+ val kernelCoroutineContext: CoroutineContext
+ get() = instance.kernel + instance.rete + DbSource(instance.kernel.dbState, instance.kernel.toString())
+
fun CoroutineScope.saga(condition: () -> Boolean = { true }, block: suspend CoroutineScope.() -> T): Deferred {
- val instance = instance
- return async(instance.kernel + instance.rete + DbSource(instance.kernel.dbState, instance.kernel.toString())) {
+ return async(kernelCoroutineContext) {
withCondition(condition, block)
}
}
diff --git a/platform/kernel/shared/src/rpc/RemoteApiProviderService.kt b/platform/kernel/shared/src/rpc/RemoteApiProviderService.kt
new file mode 100644
index 000000000000..2f0592fa1492
--- /dev/null
+++ b/platform/kernel/shared/src/rpc/RemoteApiProviderService.kt
@@ -0,0 +1,16 @@
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.platform.kernel.rpc
+
+import com.intellij.openapi.application.ApplicationManager
+import fleet.rpc.RemoteApi
+import kotlin.reflect.KClass
+
+interface RemoteApiProviderService {
+ fun > resolve(klass: KClass): T
+
+ companion object {
+ fun > resolve(klass: KClass): T {
+ return ApplicationManager.getApplication().getService(RemoteApiProviderService::class.java).resolve(klass)
+ }
+ }
+}
\ No newline at end of file
diff --git a/platform/kernel/shared/src/util/KLogger.kt b/platform/kernel/shared/src/util/KLogger.kt
new file mode 100644
index 000000000000..40f8f031fa0d
--- /dev/null
+++ b/platform/kernel/shared/src/util/KLogger.kt
@@ -0,0 +1,79 @@
+package com.intellij.platform.kernel.util
+
+import com.intellij.openapi.diagnostic.Logger
+import fleet.util.logging.*
+import kotlin.reflect.KClass
+
+class IjLogger(private val logger: Logger) : BaseLogger {
+ override val isTraceEnabled: Boolean
+ get() = logger.isTraceEnabled
+ override val isDebugEnabled: Boolean
+ get() = logger.isDebugEnabled
+ override val isInfoEnabled: Boolean
+ get() = true
+ override val isWarnEnabled: Boolean
+ get() = true
+ override val isErrorEnabled: Boolean
+ get() = true
+
+ override fun trace(message: Any?) {
+ logger.trace(message?.toString() ?: "null")
+ }
+
+ override fun trace(t: Throwable?, message: Any?) {
+ logger.trace(message?.toString() ?: "null")
+ if (t != null) {
+ logger.trace(t)
+ }
+ }
+
+ override fun debug(message: Any?) {
+ logger.debug(message?.toString() ?: "null")
+ }
+
+ override fun debug(t: Throwable?, message: Any?) {
+ logger.debug(message?.toString() ?: "null", t)
+ }
+
+ override fun info(message: Any?) {
+ logger.info(message?.toString() ?: "null")
+ }
+
+ override fun info(t: Throwable?, message: Any?) {
+ logger.info(message?.toString() ?: "null", t)
+ }
+
+ override fun warn(message: Any?) {
+ logger.warn(message?.toString() ?: "null")
+ }
+
+ override fun warn(t: Throwable?, message: Any?) {
+ logger.warn(message?.toString() ?: "null", t)
+ }
+
+ override fun error(message: Any?) {
+ logger.error(message.toString())
+ }
+
+ override fun error(t: Throwable?, message: Any?) {
+ logger.error(message?.toString() ?: "null", t)
+ }
+}
+
+class IjLoggerFactory : KLoggerFactory {
+ override fun logger(owner: KClass<*>): KLogger {
+ return KLogger(IjLogger(Logger.getInstance(owner.java)))
+ }
+
+ override fun logger(owner: Class<*>): KLogger {
+ return KLogger(IjLogger(Logger.getInstance(owner)))
+ }
+
+ override fun logger(owner: Any): KLogger {
+ return KLogger(IjLogger(Logger.getInstance(owner.toString())))
+ }
+
+ override fun logger(name: String): KLogger {
+ return KLogger(IjLogger(Logger.getInstance(name)))
+ }
+}
\ No newline at end of file
diff --git a/platform/ide-core/src/com/intellij/kernel/ReadTrackingIndex.kt b/platform/kernel/shared/src/util/ReadTrackingIndex.kt
similarity index 98%
rename from platform/ide-core/src/com/intellij/kernel/ReadTrackingIndex.kt
rename to platform/kernel/shared/src/util/ReadTrackingIndex.kt
index 3d5d8b9ea327..eb8e24684a49 100644
--- a/platform/ide-core/src/com/intellij/kernel/ReadTrackingIndex.kt
+++ b/platform/kernel/shared/src/util/ReadTrackingIndex.kt
@@ -1,5 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.kernel
+package com.intellij.platform.kernel.util
import com.jetbrains.rhizomedb.Datom
import com.jetbrains.rhizomedb.Pattern
@@ -9,6 +9,7 @@ import it.unimi.dsi.fastutil.ints.IntConsumer
import it.unimi.dsi.fastutil.ints.IntOpenHashSet
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
import it.unimi.dsi.fastutil.longs.LongOpenHashSet
+import kotlin.collections.set
internal class ReadTrackingIndex : ReadTrackingContext {
companion object {
diff --git a/platform/ide-core/src/com/intellij/kernel/Entities.kt b/platform/kernel/shared/src/util/entities.kt
similarity index 92%
rename from platform/ide-core/src/com/intellij/kernel/Entities.kt
rename to platform/kernel/shared/src/util/entities.kt
index ca61b22103b6..c1ba51bb702b 100644
--- a/platform/ide-core/src/com/intellij/kernel/Entities.kt
+++ b/platform/kernel/shared/src/util/entities.kt
@@ -1,5 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.kernel
+package com.intellij.platform.kernel.util
import com.jetbrains.rhizomedb.CascadeDeleteBy
import com.jetbrains.rhizomedb.Unique
diff --git a/platform/ide-core/src/com/intellij/kernel/KernelService.kt b/platform/kernel/shared/src/util/kernelUtils.kt
similarity index 73%
rename from platform/ide-core/src/com/intellij/kernel/KernelService.kt
rename to platform/kernel/shared/src/util/kernelUtils.kt
index c20c55e549c4..18ff2ce1f129 100644
--- a/platform/ide-core/src/com/intellij/kernel/KernelService.kt
+++ b/platform/kernel/shared/src/util/kernelUtils.kt
@@ -1,7 +1,6 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.kernel
+package com.intellij.platform.kernel.util
-import com.intellij.fleet.kernel.KernelService
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.asContextElement
import com.intellij.util.concurrency.annotations.RequiresEdt
@@ -11,7 +10,6 @@ import fleet.kernel.Kernel
import fleet.kernel.KernelMiddleware
import fleet.kernel.kernel
import fleet.kernel.rebase.*
-import fleet.kernel.rete.Rete
import fleet.kernel.rete.withRete
import fleet.kernel.subscribe
import fleet.rpc.core.Serialization
@@ -26,7 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger
@ApiStatus.Internal
@ApiStatus.Experimental
-suspend fun withKernel(scope: CoroutineScope, middleware: KernelMiddleware, body: suspend () -> T) {
+suspend fun withKernel(middleware: KernelMiddleware, body: suspend () -> T) {
val entityClasses = listOf(Kernel::class.java.classLoader).flatMap(::collectEntityClasses)
fleet.kernel.withKernel(entityClasses, middleware = middleware) { currentKernel ->
withRete {
@@ -99,30 +97,6 @@ object ReadTracker {
}
}
-val FleetRpcSerialization = Serialization(SerializersModule {
+val KernelRpcSerialization = Serialization(SerializersModule {
registerCRUDInstructions()
})
-
-class BaseKernelService(coroutineScope: CoroutineScope) : KernelService {
- private val kernelDeferred: CompletableDeferred = CompletableDeferred()
- private val reteDeferred : CompletableDeferred = CompletableDeferred()
-
- init {
- coroutineScope.launch(start = CoroutineStart.ATOMIC) {
- withKernel(this, middleware = LeaderKernelMiddleware(FleetRpcSerialization, CommonInstructionSet.encoder())) {
- kernelDeferred.complete(kernel())
- reteDeferred.complete(currentCoroutineContext()[Rete]!!)
- ReadTracker.subscribeForChanges()
- }
- }
- runBlocking {
- kernelDeferred.await()
- reteDeferred.await()
- }
- }
-
- override val kernel: Kernel
- get() = kernelDeferred.getCompleted()
- override val rete: Rete
- get() = reteDeferred.getCompleted()
-}
\ No newline at end of file
diff --git a/platform/ide-core/src/com/intellij/kernel/Model.kt b/platform/kernel/shared/src/util/models.kt
similarity index 98%
rename from platform/ide-core/src/com/intellij/kernel/Model.kt
rename to platform/kernel/shared/src/util/models.kt
index 9c53b879209b..5508be49c625 100644
--- a/platform/ide-core/src/com/intellij/kernel/Model.kt
+++ b/platform/kernel/shared/src/util/models.kt
@@ -1,7 +1,7 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.kernel
+package com.intellij.platform.kernel.util
-import com.intellij.fleet.kernel.KernelService
+import com.intellij.platform.kernel.KernelService
import com.intellij.util.concurrency.annotations.RequiresEdt
import com.jetbrains.rhizomedb.EID
import com.jetbrains.rhizomedb.entity
@@ -153,7 +153,6 @@ private class ModelChangeScopeImpl(val sharedChangeScope: SharedChangeScope) : M
val value = serialization.json.encodeToJsonElement(serialization.kSerializer(ktype), value)
val viewModel = lookupOne(ViewModelEntity::modelId, id)
if (viewModel == null) {
- println("Aha")
throw IllegalStateException("ViewModelEntity not found for model $id")
}
val alreadyExist = lookupOne(ModelPropertyEntity::id, fqn)