From Andrew: On Monday 05 October 2009 10:24:25 Jeff Hill wrote: > > In the short term: > Clients _are_ currently allowed to _not_ specify the element count when > they subscribe (they can specify an element count of zero). So perhaps > the CA code should be changed allowing the array length to be dynamic in > just that situation. Currently, we are locking the element count for that > situation to what was there when the channel connects, but perhaps this is > wrong (lazy) etc. Any opinions from Andrew or others? I agree with Michael in favor of changing the behavior so that when a client specifies COUNT=0 in its subscription, it is requesting a dynamic element count such that successive events may have different numbers of elements. However it should never be given more than ca_element_count() elements so it can always use that number to allocate data storage at connection time. If at some time in the future we want to make it possible for even that number to be increased, this could be indicated to the client by a pair of disconnect/ reconnect events. Looking at my Perl 5 API code, I don't currently allow the user to specify COUNT=0 but if I change just that the above behavior should work perfectly since I use peha->count in the callback routine to allocate the array storage. I suspect the same would be true of a number of other clients. It would be interesting to consider whether doing a ca_array_get_callback() with COUNT=0 should copy the new subscription behavior and return all of the current elements as well. I did wonder whether that should return the current number of elements without fetching all the data, but I don't think it should, the problem being that users might assume they can use that to allocate the storage for the data, but the IOC might change the data length in between that request and the following one that actually gets the data. > We would need an efficient way to > query the current element count before each call to db_get_field. That might get slightly complicated. The dbGetField() routine that it uses calls dbScanLock(precord) at the beginning and dbScanUnlock(precord) at the end, but we can't allow the record to be processed in between fetching the size and the actual data. I really don't like the idea of putting a wrapping dbScanLock() call in some new db_get_nelements() routine and the corresponding dbScanUnlock() in the db_get_field() routine. I think the best solution would be to change the int no_elements parameter of db_get_field() into an int* and change its value inside the routine, just like dbGetField() does. This would still require the server to allocate the buffer for the full array before entry (which it already has to do), but it could reclaim the unused part immediately afterward. Note that the task of padding the remaining buffer with zeros which db_get_field() currently does could even be moved into the client library (if the client asked for a fixed length subscription and not the dynamic one that we're discussing). > Clients should probably have flexibility to specify, or not, for each > bound on the hypercube (multidimensional array). Am I off base on that as a > future direction for the API design? Open to suggestions. > And, of course, also a first element number for each bound on the hypercube > - so that one can define a slice. That certainly makes sense when we come to supporting multidimensional data, but at the moment we only provide the metadata for a single dimension and it would be nice to solve this problem with only a small change to the existing API.