Add magix registry access service

This commit is contained in:
Alexander Nozik 2023-08-18 13:01:46 +03:00
parent 82dbb3a1f0
commit a9f29f92ca
3 changed files with 103 additions and 2 deletions

39
controls-core/README.md Normal file
View File

@ -0,0 +1,39 @@
# Module controls-core
## Features
- [device](src/commonMain/kotlin/space/kscience/controls/api/Device.kt) : Device API with subscription (asynchronous and pseudo-synchronous properties)
- [deviceMessage](src/commonMain/kotlin/space/kscience/controls/api/DeviceMessage.kt) : Specification for messages used to communicate between Controls-kt devices.
- [deviceHub](src/commonMain/kotlin/space/kscience/controls/api/DeviceHub.kt) : Grouping of devices into local tree-like hubs.
## Usage
## Artifact:
The Maven coordinates of this project are `space.kscience:controls-core:0.2.0-dev-2`.
**Gradle Groovy:**
```groovy
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:controls-core:0.2.0-dev-2'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:controls-core:0.2.0-dev-2")
}
```

32
controls-pi/README.md Normal file
View File

@ -0,0 +1,32 @@
# Module controls-pi
## Usage
## Artifact:
The Maven coordinates of this project are `space.kscience:controls-pi:0.2.0-dev-2`.
**Gradle Groovy:**
```groovy
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:controls-pi:0.2.0-dev-2'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:controls-pi:0.2.0-dev-2")
}
```

View File

@ -2,7 +2,9 @@ package space.kscience.magix.services
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -57,6 +59,9 @@ public class MagixRegistryErrorMessage(
public val errorMessage: String? = null, public val errorMessage: String? = null,
) : MagixRegistryMessage() ) : MagixRegistryMessage()
/**
* Launch a magix registry loop service based on local registry
*/
public fun CoroutineScope.launchMagixRegistry( public fun CoroutineScope.launchMagixRegistry(
endpoint: MagixEndpoint, endpoint: MagixEndpoint,
registry: MagixRegistry, registry: MagixRegistry,
@ -71,7 +76,7 @@ public fun CoroutineScope.launchMagixRegistry(
MagixRegistryMessage.format, MagixRegistryMessage.format,
MagixRegistryValueMessage(payload.propertyName, value ?: JsonNull) MagixRegistryValueMessage(payload.propertyName, value ?: JsonNull)
) )
} catch (ex: Exception){ } catch (ex: Exception) {
endpoint.send( endpoint.send(
MagixRegistryMessage.format, MagixRegistryMessage.format,
MagixRegistryErrorMessage(payload.propertyName, ex::class.simpleName, ex.message) MagixRegistryErrorMessage(payload.propertyName, ex::class.simpleName, ex.message)
@ -79,3 +84,28 @@ public fun CoroutineScope.launchMagixRegistry(
} }
} }
}.launchIn(this) }.launchIn(this)
/**
* Request a property with given name and return a [Flow] of pairs (sourceEndpoint, value).
*
* Flow is ordered by response receive time.
* The subscriber can terminate the flow at any moment to stop subscription, or use it indefinitely to continue observing changes.
* To request a single value, use [Flow.first] function.
*
* If [targetEndpoint] field is provided, send request only to given endpoint.
*/
public suspend fun MagixEndpoint.getProperty(
propertyName: String,
user: JsonElement? = null,
targetEndpoint: String? = null,
): Flow<Pair<String, JsonElement>> {
send(MagixRegistryMessage.format, MagixRegistryRequestMessage(propertyName), target = targetEndpoint, user = user)
return subscribe(
MagixRegistryMessage.format,
originFilter = targetEndpoint?.let { setOf(it) }
).mapNotNull { (message, response) ->
if (response is MagixRegistryValueMessage && response.propertyName == propertyName) {
message.sourceEndpoint to response.value
} else null
}
}