Fix loading duplicating plugins in visionServer

This commit is contained in:
Alexander Nozik 2022-11-23 13:41:36 +03:00
parent 4ceffef67a
commit d6c974fcbc
No known key found for this signature in database
GPG Key ID: F7FCF2DD25C71357
3 changed files with 21 additions and 18 deletions

View File

@ -24,7 +24,7 @@ public interface MutableVisionContainer<in V : Vision> {
* A serializable representation of [Vision] children container * A serializable representation of [Vision] children container
*/ */
public interface VisionChildren : VisionContainer<Vision> { public interface VisionChildren : VisionContainer<Vision> {
public val group: Vision? public val parent: Vision?
public val keys: Set<NameToken> public val keys: Set<NameToken>
@ -35,7 +35,7 @@ public interface VisionChildren : VisionContainer<Vision> {
public operator fun get(token: NameToken): Vision? public operator fun get(token: NameToken): Vision?
override fun getChild(name: Name): Vision? = when (name.length) { override fun getChild(name: Name): Vision? = when (name.length) {
0 -> group 0 -> parent
1 -> get(name.first()) 1 -> get(name.first())
else -> get(name.first())?.children?.getChild(name.cutFirst()) else -> get(name.first())?.children?.getChild(name.cutFirst())
} }
@ -44,7 +44,7 @@ public interface VisionChildren : VisionContainer<Vision> {
public const val STATIC_TOKEN_BODY: String = "@static" public const val STATIC_TOKEN_BODY: String = "@static"
public fun empty(owner: Vision): VisionChildren = object : VisionChildren { public fun empty(owner: Vision): VisionChildren = object : VisionChildren {
override val group: Vision get() = owner override val parent: Vision get() = owner
override val keys: Set<NameToken> get() = emptySet() override val keys: Set<NameToken> get() = emptySet()
override val changes: Flow<Name> get() = emptyFlow() override val changes: Flow<Name> get() = emptyFlow()
override fun get(token: NameToken): Vision? = null override fun get(token: NameToken): Vision? = null
@ -64,7 +64,7 @@ public inline fun VisionChildren.forEach(block: (NameToken, Vision) -> Unit) {
public interface MutableVisionChildren : VisionChildren, MutableVisionContainer<Vision> { public interface MutableVisionChildren : VisionChildren, MutableVisionContainer<Vision> {
public override val group: MutableVisionGroup public override val parent: MutableVisionGroup
public operator fun set(token: NameToken, value: Vision?) public operator fun set(token: NameToken, value: Vision?)
@ -85,7 +85,7 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer<
else -> { else -> {
val currentParent = get(name.first()) val currentParent = get(name.first())
if (currentParent != null && currentParent !is MutableVisionGroup) error("Can't assign a child to $currentParent") if (currentParent != null && currentParent !is MutableVisionGroup) error("Can't assign a child to $currentParent")
val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: group.createGroup().also { val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: parent.createGroup().also {
set(name.first(), it) set(name.first(), it)
} }
parent.children.setChild(name.cutFirst(), child) parent.children.setChild(name.cutFirst(), child)
@ -125,7 +125,7 @@ public fun <V : Vision> MutableVisionContainer<V>.setChild(
): Unit = setChild(str?.parseAsName(), vision) ): Unit = setChild(str?.parseAsName(), vision)
internal abstract class VisionChildrenImpl( internal abstract class VisionChildrenImpl(
override val group: MutableVisionGroup, override val parent: MutableVisionGroup,
) : MutableVisionChildren { ) : MutableVisionChildren {
private val updateJobs = HashMap<NameToken, Job>() private val updateJobs = HashMap<NameToken, Job>()
@ -140,7 +140,7 @@ internal abstract class VisionChildrenImpl(
return items!! return items!!
} }
private val scope: CoroutineScope? get() = group.manager?.context private val scope: CoroutineScope? get() = parent.manager?.context
override val keys: Set<NameToken> get() = items?.keys ?: emptySet() override val keys: Set<NameToken> get() = items?.keys ?: emptySet()
@ -170,9 +170,9 @@ internal abstract class VisionChildrenImpl(
} else { } else {
(items ?: buildItems())[token] = value (items ?: buildItems())[token] = value
//check if parent already exists and is different from the current one //check if parent already exists and is different from the current one
if (value.parent != null && value.parent != group) error("Can't reassign parent Vision for $value") if (value.parent != null && value.parent != parent) error("Can't reassign parent Vision for $value")
//set parent //set parent
value.parent = group value.parent = parent
//start update jobs (only if the vision is rooted) //start update jobs (only if the vision is rooted)
scope?.let { scope -> scope?.let { scope ->
val job = value.children?.changes?.onEach { val job = value.children?.changes?.onEach {

View File

@ -1,10 +1,7 @@
package space.kscience.visionforge.server package space.kscience.visionforge.server
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.Application import io.ktor.server.application.*
import io.ktor.server.application.call
import io.ktor.server.application.install
import io.ktor.server.application.log
import io.ktor.server.cio.CIO import io.ktor.server.cio.CIO
import io.ktor.server.engine.ApplicationEngine import io.ktor.server.engine.ApplicationEngine
import io.ktor.server.engine.embeddedServer import io.ktor.server.engine.embeddedServer
@ -18,6 +15,7 @@ import io.ktor.server.routing.*
import io.ktor.server.util.getOrFail import io.ktor.server.util.getOrFail
import io.ktor.server.websocket.WebSockets import io.ktor.server.websocket.WebSockets
import io.ktor.server.websocket.webSocket import io.ktor.server.websocket.webSocket
import io.ktor.util.pipeline.Pipeline
import io.ktor.websocket.Frame import io.ktor.websocket.Frame
import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.channels.consumeEach
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
@ -270,6 +268,11 @@ public class VisionServer internal constructor(
} }
} }
public fun <P : Pipeline<*, ApplicationCall>, B : Any, F : Any> P.require(
plugin: Plugin<P, B, F>,
configure: B.() -> Unit = {},
): F = pluginOrNull(plugin) ?: install(plugin, configure)
/** /**
* Attach VisionForge server application to given server * Attach VisionForge server application to given server
*/ */
@ -278,8 +281,8 @@ public fun Application.visionServer(
webServerUrl: Url, webServerUrl: Url,
path: String = DEFAULT_PAGE, path: String = DEFAULT_PAGE,
): VisionServer { ): VisionServer {
install(WebSockets) require(WebSockets)
install(CORS) { require(CORS) {
anyHost() anyHost()
} }
@ -287,7 +290,7 @@ public fun Application.visionServer(
// install(CallLogging) // install(CallLogging)
// } // }
val serverRoute = install(Routing).createRouteFromPath(path) val serverRoute = require(Routing).createRouteFromPath(path)
serverRoute { serverRoute {
static { static {

View File

@ -124,7 +124,7 @@ public class SolidReference(
override val children: VisionChildren override val children: VisionChildren
get() = object : VisionChildren { get() = object : VisionChildren {
override val group: Vision get() = this@SolidReference override val parent: Vision get() = this@SolidReference
override val keys: Set<NameToken> get() = prototype.children?.keys ?: emptySet() override val keys: Set<NameToken> get() = prototype.children?.keys ?: emptySet()
@ -198,7 +198,7 @@ internal class SolidReferenceChild(
override val children: VisionChildren = object : VisionChildren { override val children: VisionChildren = object : VisionChildren {
override val group: Vision get() = this@SolidReferenceChild override val parent: Vision get() = this@SolidReferenceChild
override val keys: Set<NameToken> get() = prototype.children?.keys ?: emptySet() override val keys: Set<NameToken> get() = prototype.children?.keys ?: emptySet()