Open mdavidsaver opened 6 years ago
I can see that at minimum, group members need the option for force, or prohibit, processing as is already available for single Puts as a pvRequest option.
This is probably an ignorant question but does dbProcess have to follow immediately after each dbPut? In other words, would this be possible in a group put:
dbScanLock("output:step1")
dbScanLock("output:step2")
dbPut("output:step1", ...)
dbPut("output:step2", ...)
if(scanPassive("output:step1") dbProcess("output:step1")
if(scanPassive("output:step2") dbProcess("output:step2")
dbScanUnLock("output:step1")
dbScanUnLock("output:step2")
For the use case that I had in mind this would be OK, as far as I can think now.
We have been discussing this at one of our f2f meetings, not sure what we ended with.
My original idea was: If we consider a group put as an atomic operation, no processing should happen between setting elements. Processing should be explicitly specified as part of the mapping (for each field: process this record or not, process order). Client only specifies if the whole configured thing takes place or not.
I remember arguments: Could be done by specifying .PROC fields as either visible or hidden fields inside the structure. What if records in the group process other records in the group?
Note that IIRC monitors on PP fields are not sent by dbPut() - the database relies on processing happening as a result of the put. This breaks if group puts suppress processing.
I don’t think it’s any field’s PP status that normally suppresses generating monitors, IIRC that only applies to to VAL fields that are PP. The DBD file has no way to notify the IOC whether a particular field will generate a monitor on processing, and in most cases those might be conditional anyway (the Recore Reference column Rec Proc Monitor can’t be derived from the DBD info). However @ralphlange ‘s point still applies: if a group write modifies a PP VAL field but never processes the record no monitor will be fired, although that’s no different than using a DB link that is marked NPP.
This is probably an ignorant question but does dbProcess have to follow immediately after each dbPut?
No. Doing this would avoid sending monitor updates with intermediate values, but still sends extra updates.
I opted to start with things this way because "like a sequence of caput" seems easier for experienced users to reason about. I'm open to finding a better way though.
To elaborate on https://github.com/epics-base/pva2pva/issues/15#issuecomment-376975196 I'm thinking to add a mapping option like +pp:true
with possible values being: true, false, or null (default/passive).
With this code change, and some extra 'PP' in your example, I think I can get the effect you're after.
record(ao, "output:step1") {
field(PINI, "YES")
field(FLNK, "outputvalue")
info(Q:group, {
"output:table":{
"":{+type:"meta", +channel:"VAL"},
"value.stepone":{+type:"plain",+channel:"VAL",+putorder:1,+pp:false}
}
})
}
... output:step2 omitted ...
record(calc, "outputvalue") {
field(CALC, "A+B")
field(INPA, "output:step1 PP") # added PP
field(INPB, "output:step2 PP")
info(Q:group, {
"_fake": {+type:"proc", +channel:"VAL", +putorder:2, +trigger:"*"}
}
}
This would make a group put equivalent to
dbScanLock("output:step1");
dbScanLock("output:step2");
dbScanLock("outputvalue");
dbPut("output:step1", ...);
dbPut("output:step2", ...);
dbProcess("outputvalue"); // PP input links cause step1/2 to process once with new values
dbScanUnLock("output:step1");
dbScanUnLock("output:step2");
dbScanUnLock("outputvalue");
My original idea was:
I have to admit I remember only some of this argument, so we'll probably have to rehash it. This change by itself doesn't solve any fundamental problem, though it doesn't seem to introduce any new confusion. So I'm undecided...
What I see as "the fundamental problem" is the dbPutLink()/dbGetLink()/dbScanFwdLink() are recursive. I think I can see a way to avoid this for output/forward links. Where I get stuck is ordered and conditional input links w/ PP.
Still, this would be enough in Timo's case. If dbScanFwdLink() for DB_LINK only flags the target record for later processing, then the processing changes from the step1 and step2 records could be merged.
@ttkorhonen Brings up a case I hadn't considered wrt. group Put (edited for brevity).
Unlike the table example (iocBoot/iocimagedemo/table.db) where only one PV causes real action, in Timo's case changing any input may cause the output to change. Timo's expectation is that one group Put should result in "outputvalue" being processed once. However, what he does is equivalent to the pseudo-code:
The dbProcess() calls, along with the FLNKs will result in "outputvalue" being processed several times.
So the question is, how to avoid this while still preserving the behavior of single Puts?