Architecture rework

This commit is contained in:
Alexander Nozik 2021-11-20 13:13:32 +03:00
parent 099649f090
commit 85f6b81334
9 changed files with 66 additions and 41 deletions

View File

@ -95,6 +95,8 @@ public suspend fun DeviceHub.respondHubMessage(request: DeviceMessage): DeviceMe
* Collect all messages from given [DeviceHub], applying proper relative names
*/
public fun DeviceHub.hubMessageFlow(scope: CoroutineScope): Flow<DeviceMessage> {
//TODO could we avoid using downstream scope?
val outbox = MutableSharedFlow<DeviceMessage>()
if (this is Device) {
messageFlow.onEach {

View File

@ -17,11 +17,5 @@ kotlin {
implementation(project(":controls-core"))
}
}
jvmMain {
dependencies {
implementation("org.jetbrains.xodus:xodus-openAPI:1.3.232")
implementation(project(":controls-xodus"))
}
}
}
}

View File

@ -1,24 +1,16 @@
package ru.mipt.npm.controls.client
import jetbrains.exodus.entitystore.PersistentEntityStore
import kotlinx.coroutines.Job
import ru.mipt.npm.controls.api.DeviceMessage
import ru.mipt.npm.controls.api.PropertyChangedMessage
import ru.mipt.npm.controls.controllers.DeviceManager
import ru.mipt.npm.controls.xodus.toEntity
import ru.mipt.npm.magix.api.MagixEndpoint
/**
* Communicate with server in [Magix format](https://github.com/waltz-controls/rfc/tree/master/1) and dump messages at xodus entity store
*/
public fun DeviceManager.connectToMagix(
endpoint: MagixEndpoint<DeviceMessage>,
endpointID: String = DATAFORGE_MAGIX_FORMAT,
entityStore: PersistentEntityStore
): Job = connectToMagix(endpoint, endpointID) { message ->
if (message.payload is PropertyChangedMessage) {
entityStore.executeInTransaction {
message.toEntity(it)
}
}
}
///**
// * Communicate with server in [Magix format](https://github.com/waltz-controls/rfc/tree/master/1) and dump messages at xodus entity store
// */
//public fun DeviceManager.connectToMagix(
// endpoint: MagixEndpoint<DeviceMessage>,
// endpointID: String = DATAFORGE_MAGIX_FORMAT,
// entityStore: PersistentEntityStore
//): Job = connectToMagix(endpoint, endpointID) { message ->
// if (message.payload is PropertyChangedMessage) {
// entityStore.executeInTransaction {
// message.toEntity(it)
// }
// }
//}

View File

@ -3,11 +3,12 @@ plugins {
`maven-publish`
}
val xodusVersion = "1.3.232"
dependencies {
implementation(projects.controlsCore)
implementation(projects.magix.magixApi)
implementation("org.jetbrains.xodus:xodus-entity-store:1.3.232")
implementation("org.jetbrains.xodus:xodus-environment:1.3.232")
implementation("org.jetbrains.xodus:xodus-vfs:1.3.232")
implementation("org.jetbrains.xodus:xodus-entity-store:$xodusVersion")
implementation("org.jetbrains.xodus:xodus-environment:$xodusVersion")
implementation("org.jetbrains.xodus:xodus-vfs:$xodusVersion")
}

View File

@ -8,12 +8,26 @@ import kotlinx.serialization.json.JsonElement
import ru.mipt.npm.controls.api.PropertyChangedMessage
import ru.mipt.npm.magix.api.MagixMessage
import space.kscience.dataforge.meta.MetaSerializer
import space.kscience.dataforge.meta.isLeaf
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.values.Value
import space.kscience.dataforge.values.ValueType
public fun PropertyChangedMessage.toEntity(transaction: StoreTransaction): Entity {
val entity = transaction.newEntity("PropertyChangedMessage")
entity.setProperty("property", property)
entity.setProperty("value", value.toString())
if (value.isLeaf) {
val v: Value = value.value ?: TODO()
when(v.type){
ValueType.NULL -> TODO()
ValueType.LIST -> TODO()
ValueType.NUMBER -> TODO()
ValueType.STRING -> TODO()
ValueType.BOOLEAN -> TODO()
}
} else {
entity.setProperty("value", value.toString())
}
entity.setProperty("sourceDevice", sourceDevice.toString())
targetDevice?.let { entity.setProperty("targetDevice", it.toString()) }
comment?.let { entity.setProperty("comment", it) }

View File

@ -0,0 +1,21 @@
package ru.mipt.npm.controls.xodus
import jetbrains.exodus.entitystore.PersistentEntityStore
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import ru.mipt.npm.controls.api.PropertyChangedMessage
import ru.mipt.npm.controls.controllers.DeviceManager
import ru.mipt.npm.controls.controllers.hubMessageFlow
public fun DeviceManager.connectXodus(
entityStore: PersistentEntityStore,
//filter: (DeviceMessage) -> Boolean = {it is PropertyChangedMessage}
): Job = hubMessageFlow(context).onEach { message ->
if (message is PropertyChangedMessage) {
entityStore.executeInTransaction {
message.toEntity(it)
}
}
}.launchIn(context)

View File

@ -19,6 +19,7 @@ dependencies {
implementation(projects.magix.magixServer)
implementation(projects.magix.magixRsocket)
implementation(projects.controlsMagixClient)
implementation(projects.controlsXodus)
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.1")

View File

@ -14,8 +14,7 @@ import space.kscience.dataforge.meta.string
import space.kscience.dataforge.names.Name
import kotlin.time.ExperimentalTime
class MagixVirtualCar(context: Context, meta: Meta)
: VirtualCar(context, meta) {
class MagixVirtualCar(context: Context, meta: Meta) : VirtualCar(context, meta) {
private suspend fun MagixEndpoint<DeviceMessage>.startMagixVirtualCarUpdate() {
launch {

View File

@ -1,20 +1,21 @@
package ru.mipt.npm.controls.demo.car
import io.ktor.server.engine.*
import io.ktor.server.engine.ApplicationEngine
import javafx.beans.property.DoubleProperty
import javafx.scene.Parent
import javafx.scene.control.TextField
import javafx.scene.layout.Priority
import javafx.stage.Stage
import jetbrains.exodus.entitystore.PersistentEntityStore
import jetbrains.exodus.entitystore.PersistentEntityStoreImpl
import jetbrains.exodus.entitystore.PersistentEntityStores
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import ru.mipt.npm.controls.api.DeviceMessage
import ru.mipt.npm.controls.client.connectToMagix
import ru.mipt.npm.controls.controllers.DeviceManager
import ru.mipt.npm.controls.controllers.install
import ru.mipt.npm.controls.demo.car.IVirtualCar.Companion.acceleration
import ru.mipt.npm.controls.xodus.connectXodus
import ru.mipt.npm.magix.api.MagixEndpoint
import ru.mipt.npm.magix.rsocket.rSocketWithTcp
import ru.mipt.npm.magix.server.startMagixServer
@ -27,6 +28,7 @@ class VirtualCarController : Controller(), ContextAware {
var magixVirtualCar: MagixVirtualCar? = null
var magixServer: ApplicationEngine? = null
var entityStore: PersistentEntityStore? = null
var storageJob: Job? =null
override val context = Context("demoDevice") {
plugin(DeviceManager)
@ -37,17 +39,16 @@ class VirtualCarController : Controller(), ContextAware {
fun init() {
context.launch {
virtualCar = deviceManager.install("virtual-car", VirtualCar)
//starting magix event loop
magixServer = startMagixServer(enableRawRSocket = true, enableZmq = true)
magixVirtualCar = deviceManager.install("magix-virtual-car", MagixVirtualCar)
entityStore = PersistentEntityStores.newInstance("/home/marvel1337/2021/SCADA/.messages")
//connect to entity store
storageJob = deviceManager.connectXodus(entityStore as PersistentEntityStore)
//Launch device client and connect it to the server
val deviceEndpoint = MagixEndpoint.rSocketWithTcp("localhost", DeviceMessage.serializer())
if (entityStore != null) {
deviceManager.connectToMagix(deviceEndpoint, entityStore = entityStore as PersistentEntityStoreImpl)
} else {
deviceManager.connectToMagix(deviceEndpoint)
}
deviceManager.connectToMagix(deviceEndpoint)
}
}