DataReady Event and consistency

Attached is an example DS and a client.

The server has an double attribute which is data ready event enabled, and a command which increments the attributes value and then generates a data ready event with the attribute value as event counter.

Sending the event:

void Test::generate_data()
{
	DEBUG_STREAM << "Test::GenerateData()  - " << device_name << endl;
	/*—– PROTECTED REGION ID(Test::generate_data) ENABLED START —–*/

  *attr_data_read += 1;
  push_data_ready_event("data", *attr_data_read);

	/*—– PROTECTED REGION END —–*/	//	Test::generate_data
}


Receiving it:

  virtual void push_event(Tango::DataReadyEventData *e) override
  {
    if(e->err)
    {
      Tango::Except::print_error_stack(e->errors);
      return;
    }

    Tango::DeviceAttribute da = e->device->read_attribute("data");
    double data;
    da >> data;

    printf("DRE: value: %05g, counter: %05d\n", data, e->ctr);
  }

Running this with tango 9.2.5 on debian stretch gives:


DRE: value: 03997, counter: 03991
DRE: value: 03998, counter: 03992
DRE: value: 03999, counter: 03993
DRE: value: 04000, counter: 03994
DRE: value: 04000, counter: 03995
DRE: value: 04000, counter: 03996
DRE: value: 04000, counter: 03997
DRE: value: 04000, counter: 03998
DRE: value: 04000, counter: 03999
DRE: value: 04000, counter: 04000

which shows that reading the attribute and receiving the event got desynchronized. Is that to be expected? Is there an alternative? My real application uses array data, so AFAIU I can not use the user events.
Hi Thomas,

Is the event being polled? If so then the client will read the cached value. Sending the event and reading it from the client is probably no guarantee that they are synchronised because of the time delay - at what frequency are you sending the events? It could also be a bug.

It could be interesting as a test to send the time (in ms) as the DataReadyEvent counter and set the attribute to the time (in ms) to see what the difference is in sending the event and receiving the event and reading the attribute. If you have a test server to send us we can try to run it on our setup.

Andy
Edited 6 years ago
Hi Andy,

no the event is not polled. I have attached the code already in the first post.

I'm sending the events from a loop


    for(int i = 0; i < 1000; i += 1)
    {
      device->command_inout("GenerateData");
    }

without any waiting time.
Hi Thomas,

Generate_data() is called at very high frequency in your case and it looks like the event callbacks do not have time to cope with it…

Please note that your callback will have to take the Tango monitor to read the attribute value so it will be in concurrency with the GenerateData command which will also take this monitor…
Since you are sending GenerateData command in a loop without sleep time, this one has more chance to get CPU time than the callback, so more chance to get the Tango Monitor.

I am not surprised by the results of your tests and I think this is what is expected.

Kind regards,
Reynald
Rosenberg's Law: Software is easy to make, except when you want it to do something new.
Corollary: The only software that's worth making is software that does something new.
Hi Thomas,

I agree with Reynald - if you are calling get_data() at full speed and then reading the attribute the values will get out of sync or at least synchronization is not guaranteed. The DataReady event was created to inform clients there is new data ready which they can come and pick up at their leisure but not to ensure synchronisation. It was thought to be used by scanning devices which want to inform clients that there is data and then wait until the client picks it up before starting a new scan.

What you need is to use push_change_events() of your spectrum attribute. The clients will receive the attribute value as an event. You can push arrays of values as attributes. More info here:

http://tango-controls.readthedocs.io/en/latest/development/device-api/generating-events.html

Andy
Thanks Reynald and Andy. I'll give the change events a shot.
 
Register or login to create to post a reply.