pvxs icon indicating copy to clipboard operation
pvxs copied to clipboard

Not possible to distinguish between scalars and arrays of length 1

Open simon-ess opened this issue 8 months ago • 3 comments

Describe the bug It is not possible at the moment to distinguish between the following records via PVAccess:

record(waveform, "one") {
    field(FTVL, "STRING")
    field(NELM, "1")
    field(INP, {const: "foo"})
}

record(stringin, "onestring") {
    field(INP, {const: "bar"})
}

This ultimately manifests in the fact that fetching and processing data from a record that is a waveform of strings typically requires some additional checks, since you get something like

$ pvget one
one 2024-06-03 14:23:52.988  foo

whereas if the array has NELM > 1 then you instead get

$ pvget two
one 2024-06-03 14:23:52.988  [foo, bar]

which is typically handled differently in e.g. pyepics, p4p, etc.

Note that this is not really restricted to PVXS, or even PVAccessCPP, but also ChannelAccess. In channel access I believe that due to the protocol there is no possible fix; in PVAccess, it should be fixable since an array of length 1 of type string is sent as an NTScalar, whereas an array of length > 1 is sent as an NTScalarArray; it should be possible to send an array of length one also as an NTScalarArray, which should fix this.

To Reproduce Steps to reproduce the behavior:

  1. Start an IOC with the db file above
  2. get the values
  3. be sad

Expected behavior This is a bit murky, because I might be proposing a breaking change in how IOCs communicate over PVAccess. I think it would be more consistent to have arrays always send as NTScalarArrays instead of NTScalars if they are length 1. But there might be a good reason for the current behaviour.

Information (please complete the following):

$ pvxs/bin/darwin-x86/pvxinfo -D
Host: darwin-x86
Target: darwin-x86 Darwin clang
Toolchain
    __cplusplus = 201103
    clang 14.0.3 (clang-1403.0.22.14.1)
    GCC 4.2.1
    _LIBCPP_VERSION 160006
Versions
    PVXS 1.2.3 (1.3.1-5-g57f79ce747f062a32eed-dirty)
    EPICS 7.0.8.1-DEV
    libevent 2.2.0-alpha-dev
Runtime
    uname() -> Darwin CIN-716194 22.6.0 Darwin Kernel Version 22.6.0: Mon Apr 22 20:54:28 PDT 2024; root:xnu-8796.141.3.705.2~1/RELEASE_X86_64 x86_64
    epicsThreadGetCPUs() -> 16
    osiLocalAddr() -> 172.18.21.40
    osiSockDiscoverBroadcastAddresses() ->
        172.18.23.255
        172.18.23.255
        192.168.205.255
Effective Client config from environment
    EPICS_PVA_ADDR_LIST=172.18.23.255 192.168.205.255
    EPICS_PVA_AUTO_ADDR_LIST=NO
    EPICS_PVA_BROADCAST_PORT=5076
    EPICS_PVA_CONN_TMO=30
    EPICS_PVA_INTF_ADDR_LIST=0.0.0.0
    EPICS_PVA_NAME_SERVERS=
    EPICS_PVA_SERVER_PORT=5075
Effective Server config from environment
    EPICS_PVAS_AUTO_BEACON_ADDR_LIST=NO
    EPICS_PVAS_BEACON_ADDR_LIST=172.18.23.255 192.168.205.255
    EPICS_PVAS_BROADCAST_PORT=5076
    EPICS_PVAS_IGNORE_ADDR_LIST=
    EPICS_PVAS_INTF_ADDR_LIST=0.0.0.0
    EPICS_PVAS_SERVER_PORT=5075

Additional context Add any other context about the problem here.

simon-ess avatar Jun 03 '24 13:06 simon-ess