paulscherrerinstitute / StreamDevice

EPICS Driver for message based I/O
GNU General Public License v3.0
28 stars 42 forks source link

Usage of PROC field since StreamDevice 2.8.0 #93

Closed chrschroeder closed 1 year ago

chrschroeder commented 1 year ago

Hello,

I stumbled over a "weird" problem with StreamDevice. One of my calcout records writes conditionally into the PROC field of a stream record to trigger processing. I didn't bother to compare the value, because OOPT= "When Non-zero" already does this for me. This worked well with StreamDevice 2.7.* but changed with StreamDevice 2.8.0 onwards. The record processes, but no message is send by StreamDevice. After some Debugging I found out, that this only happens if the value written into the PROC field is 2.

According to the code and the changelog this happens, because StreamDevice uses / evaluates the PROC field for something related to the @init handler. I am not sure why the PROC field is used for this and whether there was no other way, but in my opinion it shouldn't matter what I write into the PROC field to trigger processing. But that's the case here.

Here is a simplified example:

record(bo, "STREAMTEST:debugRecord") { field(DTYP, "stream") field(OUT, "@$(PROTO) debug() STREAMTEST") field(TPRO, "1") }

debug { out "TEST MESSAGE"; }

If you caput TEST:debugRecord.PROC 2 you will get the following message with streamDebug:

Process STREAMTEST:debugRecord 2022/11/22 11:41:55.100942 CAS-client StreamEpics.cc:858: Stream::process(STREAMTEST:debugRecord) 2022/11/22 11:41:55.100957 CAS-client StreamEpics.cc:884: Stream::process(STREAMTEST:debugRecord) start 2022/11/22 11:41:55.100965 CAS-client StreamCore.cc:427: StreamCore::startProtocol(STREAMTEST:debugRecord, startMode=StartInit) 2022/11/22 11:41:55.100973 CAS-client StreamEpics.cc:889: Stream::process(STREAMTEST:debugRecord): could not start @init protocol, status=NO_ALARM (0)

The code for this is found in StreamEpics.cc:

if (!startProtocol(record->proc==2 ? StreamCore::StartInit : StreamCore::StartNormal))
{
    debug("Stream::process(%s): could not start %sprotocol, status=%d\n",
        name(), record->proc==2 ? "@init " : "", status);
    (void) recGblSetSevr(record, status ? status : UDF_ALARM, INVALID_ALARM);
    return false;
}

It's obvious how to work around this, but maybe this can / should be fixed?

Thanks and best Regards, Christoph Schröder

dirk-zimoch commented 1 year ago

Hi Christoph,

That behavior is described here: https://paulscherrerinstitute.github.io/StreamDevice/processing.html#init (Potentially incompatible changes are highlighted.)

This change was intentional to implement a way to "reinitialize" the device with a simple caPut or through a link (and not only from the command line).

The choice of 2 was a bit arbitrary (like many things in EPICS). It assumes that most people would normally write 1 to process the record (as FLNK does). Sorry that this hit you unexpectedly.

The workaround is of course to write 1 to PROC instead.

Best regards, Dirk

chrschroeder commented 1 year ago

Hello Dirk,

thanks for the clarification. I will look through my database files if this might be an issue for other supports as well.

Best regards Christoph