Refactor server API

This commit is contained in:
Alexander Nozik 2022-12-06 17:04:13 +03:00
parent fef1df3ab4
commit d28873e796
No known key found for this signature in database
GPG Key ID: F7FCF2DD25C71357
4 changed files with 20 additions and 38 deletions

View File

@ -31,7 +31,7 @@ fun main() {
val form = VisionOfHtmlForm("form").apply {
onPropertyChange(visionManager.context) {
println(this)
println(values)
}
}
@ -71,7 +71,7 @@ fun main() {
value = "Submit"
}
}
println(form.values)
vision(form)
}

View File

@ -55,6 +55,8 @@ public class VisionChangeBuilder : MutableVisionContainer<Vision> {
private var propertyChange = MutableMeta()
private val children: HashMap<Name, VisionChangeBuilder> = HashMap()
public operator fun get(name: Name): VisionChangeBuilder? = children[name]
public fun isEmpty(): Boolean = propertyChange.isEmpty() && propertyChange.isEmpty() && children.isEmpty()
@Synchronized
@ -153,7 +155,7 @@ private fun CoroutineScope.collectChange(
*/
public fun Vision.flowChanges(
collectionDuration: Duration,
sendInitial: Boolean = false
sendInitial: Boolean = false,
): Flow<VisionChange> = flow {
val manager = manager ?: error("Orphan vision could not collect changes")
coroutineScope {
@ -161,7 +163,7 @@ public fun Vision.flowChanges(
val mutex = Mutex()
collectChange(Name.EMPTY, this@flowChanges, mutex, collector)
if(sendInitial) {
if (sendInitial) {
//Send initial vision state
val initialChange = VisionChange(vision = deepCopy(manager))
emit(initialChange)

View File

@ -69,9 +69,9 @@ public class VisionClient : AbstractPlugin() {
changeCollector.propertyChanged(visionName, propertyName, item)
}
public fun visionChanged(name: Name?, child: Vision?) {
changeCollector.setChild(name, child)
}
// public fun visionChanged(name: Name?, child: Vision?) {
// changeCollector.setChild(name, child)
// }
private fun renderVision(element: Element, name: Name, vision: Vision, outputMeta: Meta) {
vision.setAsRoot(visionManager)
@ -79,7 +79,7 @@ public class VisionClient : AbstractPlugin() {
renderer.render(element, name, vision, outputMeta)
}
private fun updateVision(element: Element, name: Name, vision: Vision?, outputMeta: Meta) {
private fun startVisionUpdate(element: Element, name: Name, vision: Vision?, outputMeta: Meta) {
element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr ->
val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) {
val endpoint = resolveEndpoint(element)
@ -130,9 +130,10 @@ public class VisionClient : AbstractPlugin() {
feedbackJob = visionManager.context.launch {
while (isActive) {
delay(feedbackAggregationTime.milliseconds)
if (!changeCollector.isEmpty()) {
send(visionManager.encodeToString(changeCollector.deepCopy(visionManager)))
changeCollector.reset()
val change = changeCollector[name] ?: continue
if (!change.isEmpty()) {
send(visionManager.encodeToString(change.deepCopy(visionManager)))
change.reset()
}
}
}
@ -192,7 +193,7 @@ public class VisionClient : AbstractPlugin() {
response.text().then { text ->
val vision = visionManager.decodeFromString(text)
renderVision(element, name, vision, outputMeta)
updateVision(element, name, vision, outputMeta)
startVisionUpdate(element, name, vision, outputMeta)
}
} else {
logger.error { "Failed to fetch initial vision state from $fetchUrl" }
@ -208,12 +209,12 @@ public class VisionClient : AbstractPlugin() {
}
logger.info { "Found embedded vision for output with name $name" }
renderVision(element, name, embeddedVision, outputMeta)
updateVision(element, name, embeddedVision, outputMeta)
startVisionUpdate(element, name, embeddedVision, outputMeta)
}
//Try to load vision via websocket
element.attributes[OUTPUT_CONNECT_ATTRIBUTE] != null -> {
updateVision(element, name, null, outputMeta)
startVisionUpdate(element, name, null, outputMeta)
}
else -> error("No embedded vision data / fetch url for $name")

View File

@ -93,12 +93,12 @@ public fun Application.serveVisionData(
webSocket("ws") {
val name: String = call.request.queryParameters.getOrFail("name")
application.log.debug("Opened server socket for $name")
val vision: Vision = resolveVision(Name.parse(name)) ?: error("Plot with id='$name' not registered")
val vision: Vision = resolveVision(Name.parse(name)) ?: error("Vision with id='$name' not registered")
launch {
for(frame in incoming) {
val data = frame.data.decodeToString()
application.log.debug("Received update: \n$data")
application.log.debug("Received update for $name: \n$data")
val change = configuration.visionManager.jsonFormat.decodeFromString(
VisionChange.serializer(), data
)
@ -113,7 +113,7 @@ public fun Application.serveVisionData(
VisionChange.serializer(),
update
)
application.log.debug("Sending update: \n$json")
application.log.debug("Sending update for $name: \n$json")
outgoing.send(Frame.Text(json))
}.collect()
}
@ -145,27 +145,6 @@ public fun Application.serveVisionData(
data: Map<Name, Vision>,
): Unit = serveVisionData(configuration) { data[it] }
//
///**
// * Compile a fragment to string and serve visions from it
// */
//public fun Route.serveVisionsFromFragment(
// consumer: TagConsumer<*>,
// sererPageUrl: Url,
// visionManager: VisionManager,
// fragment: HtmlVisionFragment,
//): Unit {
// val visions = consumer.visionFragment(
// visionManager.context,
// embedData = true,
// fetchUpdatesUrl = "$serverUrl$route/ws",
// fragment = fragment
// )
//
// serveVisionData(visionManager, visions)
//}
/**
* Serve a page, potentially containing any number of visions at a given [route] with given [header].
*/