Okay, so that part of dbCa changed in 3.16 without my realizing it, I was looking at the 3.15 version and had forgotten about the scanLinkOnce() addition, sorry my bad.
So now we need to have a discussion on whether updates from CA links with CP/CPP set should queue or cache. Maybe there could be another flag in the link to request queueing, but given that the CA event queues sending the value updates can and do throw away older updates once the queue is full I think we're better off not allowing multiple triggers to get queued up. The dbCa code doesn't queue the values, so I see little point in processing the record more than once after the last trigger has arrived and its value cached. We need to ensure that the record does process once after the last update, but I don't think we could wait for the dbNotify "finished" event. That might not happen until hours later in some cases, so I think it would be the wrong mechanism.
RPRO could do what we need if we had a way to get onceTask to do something different. How about we modify onceTask to give it a more general callback mechanism as well. It should still use the ring buffer, but maybe push variable length items to avoid wasting ring space (the push operation must be atomic, but the pulls don't need to be). A call to scanOnce() with no callback only needs to push a "process this record" command and the record pointer; a call to scanOnceCallback() needs to push "process record and callback" plus the three pointer arguments; we'd add a generic "call this" command with 2 pointer arguments.
With this the dbCa callback would lock the record, process it or set RPRO and unlock with completion checks that we need. The scanningOnce counter could become a boolean but in any case it should be zeroed in dbCaGetLink(), which is the point at which we'll have passed the latest cached value to the record so the trigger from it can expire. We no longer have a queue with an arbitrary length, and we don't process the record more than necessary.
Okay, so that part of dbCa changed in 3.16 without my realizing it, I was looking at the 3.15 version and had forgotten about the scanLinkOnce() addition, sorry my bad.
So now we need to have a discussion on whether updates from CA links with CP/CPP set should queue or cache. Maybe there could be another flag in the link to request queueing, but given that the CA event queues sending the value updates can and do throw away older updates once the queue is full I think we're better off not allowing multiple triggers to get queued up. The dbCa code doesn't queue the values, so I see little point in processing the record more than once after the last trigger has arrived and its value cached. We need to ensure that the record does process once after the last update, but I don't think we could wait for the dbNotify "finished" event. That might not happen until hours later in some cases, so I think it would be the wrong mechanism.
RPRO could do what we need if we had a way to get onceTask to do something different. How about we modify onceTask to give it a more general callback mechanism as well. It should still use the ring buffer, but maybe push variable length items to avoid wasting ring space (the push operation must be atomic, but the pulls don't need to be). A call to scanOnce() with no callback only needs to push a "process this record" command and the record pointer; a call to scanOnceCallback() needs to push "process record and callback" plus the three pointer arguments; we'd add a generic "call this" command with 2 pointer arguments.
With this the dbCa callback would lock the record, process it or set RPRO and unlock with completion checks that we need. The scanningOnce counter could become a boolean but in any case it should be zeroed in dbCaGetLink(), which is the point at which we'll have passed the latest cached value to the record so the trigger from it can expire. We no longer have a queue with an arbitrary length, and we don't process the record more than necessary.
Does that finally make some sense?