@@ -11,7 +11,7 @@ Exceptions must be handled by ApplicationCore in a way that the application deve
In case of a runtime_error exception the framework must catch the expection and report it to the DeviceModule. The DeviceModule handles this exception and preiodically tries to open the device. In case of several devices only the faulty device is blocked. Even if a device is faulty it should not block the server from starting.
If an input variable is in the error state, it sets the DataValidity flag for its DataValidityProparationExecutor (see \link spec_dataValidityPropagation \endlink) to faulty and the flag is propogated appropriately. After the exception is cleared and operation returns without a data fault flag, set DataValidity flag to ok. Furthermore, the device must be reinitialised automatically and also recover the values of process variables as the device might have rebooted and the variables have been re-set.
If an input variable is in the error state, it sets the DataValidity flag for its DataValidityCounter (see \link spec_dataValidityPropagation \endlink) to faulty and the flag is propogated appropriately. After the exception is cleared and operation returns without a data fault flag, set DataValidity flag to ok. Furthermore, the device must be reinitialised automatically and also recover the values of process variables as the device might have rebooted and the variables have been re-set.
<b>1. Genesis</b>
- a (removed)
...
...
@@ -21,7 +21,7 @@ If an input variable is in the error state, it sets the DataValidity flag for it
- e. An ExceptionHandlingDecorator is placed around all NDRegisterAccessors which connect a device to a ApplicationModule or fanout. (*)
- f. (removed)
- g. By default a recovery accessor is added for each device register when it is obtianed. These recovery accessors are used to correctly set the values of variables when the device is opened for the first time and after a device is recovered from an exception. (*)
- h. An ExceptionHandlingDecorator for an input knows its DataValidityProparationExecutor, which lives in the ApplicationModule or fanout that reads the input. Like this it can propagate the
- h. An ExceptionHandlingDecorator for an input knows its DataValidityCounter, which lives in the ApplicationModule or fanout that reads the input. Like this it can propagate the
dataValidity flag. Outputs do not send DataValidity faulty in case of exceptions (see \link spec_dataValidityPropagation \endlink).
- i. Write should not block in case of an exception for the outputs of ThreadedFanOut / TriggerFanOut. (*)
- j. Exception handling and invalid flag propagation has to be implemented such that it is transparent to a module whether it is directly connected to a device, or whether a fanout or another application module is in between.
* Explain DataValidityProparationExecutor and MetaDataPropagatingRegisterDecorator
* Explain use case ApplicationModule and TriggerFanOut
* Explain interaction with exception handling
Specification version v1.0 and extension v1.1
1. General idea
---------------
### 1.1 Version v1.0
* 1.1.1 In ApplicationCore each variable has a data validiy flag attached to it. ChimeraTK::DataValidity can be 'ok' or 'faulty'.
* 1.1.2 This flag is automatically propagated: If one of the inputs of an ApplicationModule is faulty, all outputs of this module will automatically be flagged as faulty.
Fan-outs might be special cases (see 2.4).
* 1.1.3 If a device is in error state, all variables which are read from it shall be marked as 'faulty'. This flag is then propagated through all the modules (via 1.1.2) so it shows up in the control system.
* 1.1.4 The user has the possibility to query the data validity of the module
* 1.1.5 The user has the possibility to set the data validity of the module to 'faulty'. However, the user cannot actively set the module to 'ok' if one of the inputs is 'faulty'.
### 1.2 Extension v1.1
* 1.2.1 The user can decide to flag individual outputs as bad. However, the user cannot actively set an output to 'ok' if the data validity of the module is 'faulty' (to be more precise: if the validity of the corresponding DataValidityCounter is faulty).
* 1.2.2 The user can get the data validity flag of its inputs and take special actions in case no invalid data shall be processed.
2. Technical implementation
---------------------------
### 2.1 MetaDataPropagatingRegisterDecorator (*)
* 2.1.1 Each input and each output of a module (or fan out) is decorated with a ChimeraTK::MetaDataPropagatingRegisterDecorator.
* 2.1.2 The decorator knows about the DataValidityCounter to which it is associated.
* 2.1.3 **read:** For each read operation it checks the incoming data validity and informs the associated ChimeraTK::DataValidityCounter about the status.
* 2.1.4 **write: (Version 1.0)** When writing, the decorator is getting the validity flag from the DataValidityCounter and attaches it to the outgoing data.
* 2.1.5 **write: (Extension 1.1)** When writing, the decorator is checking the validity flags of the DataValidityCounter and the individual flag of the output. Only if both are 'ok' the output validity is 'ok', otherwise the outgoing data is send as 'faulty'.
### 2.2 DataValidityCounter
* 2.2.1 A ChimeraTK::DataValidityCounter is assciated with several inputs and outputs (usually all inputs and outsput of a module, see section about ApplicationModules below).
* 2.2.2 It has an internal counter variable to keep track how many inputs have reported a data fault.
* 2.2.3 The overall data validity is only 'ok' if the counter is zero (all inputs have validity 'ok), otherwise the overall data validity is 'faulty'.
### 2.3 ApplicationModule
* 2.3.1 Each ApplicationModule has one DataValidityCounter.
* 2.3.2 All inputs and output are connected to it.
* 2.3.3 The main loop of the module usualy does not care about data validity. If any input is invalid, all outputs are automatically invalid. The loop just runs through normaly, even if an inputs has invalid data. (*)
### 2.4 TriggerFanOut
The TriggerFanOut is special in the sense that it does not compute anything, but reads multiple independent poll-type inputs when a trigger arrived, and pushes them out. In contrast to an ApplicationModule or one of the data fan-outs, their data validity is not connected. The trigger conceptually has data type 'void', so it cannot be invalid.
* 2.4.1 The TriggerFanOut instantiates one DataValidityCounter for each input variable.
* 2.4.2 The connection code associates the input and all corresponding outputs to the correct DataValidityCounter.
### 2.5 Interaction with exception handling (see. @ref exceptionHandlingDesign)
* 2.5.1 Like the MetaDataPropagatingRegisterDecorator, also the ExceptionHandlingDecorators of the module inputs are associated with the DataValidityCounter.
* 2.5.2 If a device accessors throws an exception, the ExceptionHandlingDecorator also increases the data fault counter, and decreases it once the device is available again.
* 2.5.3 The first failing read returns with the old data and the 'faulty' flag. Like this the flag is propagates to the outputs. Only further reads might block.
### Comments:
* to 2.1 The MetaDataPropagatingRegisterDecorator also propagates the version number, not only the data validity flag. Hence it's not called DataValidityPropagatingRegisterDecorator.
* to 2.3.3 If there would be some outputs which are still valid if a particular input is faulty it means that they are not connected to that input. This usualy is an indicator that the module is doing unrelated things and should be split.
3. Implementation details
-------------------------
* 3.1 The DataValidityCounter is a helper class around the counter variable. It facilitates instantiation and evaluation of the counter.
* 3.2 The decorators which manipulate the data fault counter are responsible for counting up and down in pairs, such that the counter goes back to 0 if all data is ok, and never becomes negative.
* 3.3 To 2.1.2 and 2.2.1: Associated means that the MetaDataPropagatingRegisterDecorator or ExceptionHandlingDecorator gets a pointer or reference to the DataValidityCounter. It does not own it. As the calling code of the decorator is executed in the main loop of the module or fan-out which owns the Executor it should be safe to shut this down.
* 3.4 Interface of the DataValidityCounter (implements 2.2)
* 3.4.1 The counter is protected. I is increased and decreased through incrementDataFaultCounter() and decrementDataFalutCounter().
* 3.4.2 The counter is a signed integer. The decrement functions has an assertions that the counter does not become negative. This simplifies debugging in case the calling code does not execute the increment and decrement in pairs.
* 3.4.3 A conveninece function getDataValidity() checks whether the counter is 0 and returns 'ok' or 'faulty' accordingly. This is just to avoid the if-statement and picking the right return value in all using code.
* 3.5 Inside the ApplicationModule main loop the module's DataValidityCounter is accessible. The user can call incrementDataFaultCounter() and decrementDataFalutCounter(), but he has to be careful to do this in pairs. The more common use case will be to query the module's data validity.
4. Known issues
---------------
* 4.1 The extension v1.1 needs an extension of the accessor interface.
* 4.1.1 Inputs need a function to query its data validity (implements 1.2.2).
* 4.1.2 The outputs need a 'setDataValidity()' function. When set to 'faulty', the output stays 'faulty' until it is set back to 'ok' (implements 1.2.1).