Error propagation for DeviceBase

This commit is contained in:
Alexander Nozik 2020-09-08 10:44:42 +03:00
parent 4b5bc40a4f
commit 540e72231b

View File

@ -5,14 +5,11 @@ import hep.dataforge.control.api.Device
import hep.dataforge.control.api.DeviceListener import hep.dataforge.control.api.DeviceListener
import hep.dataforge.control.api.PropertyDescriptor import hep.dataforge.control.api.PropertyDescriptor
import hep.dataforge.meta.MetaItem import hep.dataforge.meta.MetaItem
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
/** /**
* Baseline implementation of [Device] interface * Baseline implementation of [Device] interface
@ -104,9 +101,9 @@ public abstract class DeviceBase : Device {
//backup current value //backup current value
val currentValue = value val currentValue = value
return if (force || currentValue == null) { return if (force || currentValue == null) {
val res = withContext(scope.coroutineContext) { //all device operations should be run on device context
//all device operations should be run on device context //propagate error, but do not fail scope
//TODO add error catching val res = withContext(scope.coroutineContext + SupervisorJob(scope.coroutineContext[Job])) {
getter(currentValue) getter(currentValue)
} }
updateLogical(res) updateLogical(res)
@ -167,8 +164,7 @@ public abstract class DeviceBase : Device {
if (item == value) return@withLock if (item == value) return@withLock
val oldValue = value val oldValue = value
//all device operations should be run on device context //all device operations should be run on device context
withContext(scope.coroutineContext) { withContext(scope.coroutineContext + SupervisorJob(scope.coroutineContext[Job])) {
//TODO add error catching
setter(oldValue, item)?.let { setter(oldValue, item)?.let {
updateLogical(it) updateLogical(it)
} }
@ -206,11 +202,14 @@ public abstract class DeviceBase : Device {
override val descriptor: ActionDescriptor, override val descriptor: ActionDescriptor,
private val block: suspend (MetaItem<*>?) -> MetaItem<*>?, private val block: suspend (MetaItem<*>?) -> MetaItem<*>?,
) : Action { ) : Action {
override suspend fun invoke(arg: MetaItem<*>?): MetaItem<*>? = block(arg).also { override suspend fun invoke(arg: MetaItem<*>?): MetaItem<*>? =
notifyListeners { withContext(scope.coroutineContext + SupervisorJob(scope.coroutineContext[Job])) {
actionExecuted(name, arg, it) block(arg).also {
notifyListeners {
actionExecuted(name, arg, it)
}
}
} }
}
} }
/** /**