Skip to content
Snippets Groups Projects
Unverified Commit ee5576f0 authored by Martin Christoph Hierholzer's avatar Martin Christoph Hierholzer Committed by GitHub
Browse files

do not send out identical time stamps on the same property (#67)

Identical time stamps are considered to have identical data when DOOCS checks for inconsistencies on silent ZeroMQ connections. If on the same property new data is set without changing the VersionNumber, the timestamp will now be altered by 1 microsecond.

This is more like a temporary work around. A feature request to DOOCS should be made to introduce a distinction between a "server timestamp" and a "source timestamp" like it is realised in OPC UA.

Also a potential better solution to the other part of the problem inside ApplicationCore is described here: https://redmine.msktools.desy.de/issues/9723 
parent 9a7e0871
No related branches found
No related tags found
No related merge requests found
......@@ -155,23 +155,25 @@ namespace ChimeraTK {
this->fill_array(dataPtr, processVector.size());
modified = true;
// Convert time stamp from version number in Unix time (seconds and microseconds).
// Note that epoch of std::chrono::system_time might be different from Unix time, and Unix time omits leap seconds
// and hence is not the duration since the epoch! We have to convert to time_t and then find out the microseconds.
auto timestamp = _processArray->getVersionNumber().getTime();
auto seconds = std::chrono::system_clock::to_time_t(timestamp);
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(
timestamp - std::chrono::system_clock::from_time_t(seconds))
.count();
this->set_tmstmp(seconds, microseconds);
// Convert time stamp from version number to DOOCS timestamp
doocs::Timestamp timestamp(_processArray->getVersionNumber().getTime());
// Make sure we never send out two absolute identical time stamps. If we would do so, the "watchdog" which
// corrects inconsistencies in ZeroMQ subscriptions between sender and subcriber cannot detect the inconsistency.
if(this->get_timestamp() == timestamp) {
timestamp += std::chrono::microseconds(1);
}
this->set_timestamp(timestamp);
if(_macroPulseNumberSource) this->set_mpnum(_macroPulseNumberSource->accessData(0));
// send data via ZeroMQ if enabled and if DOOCS initialisation is complete
if(publishZMQ && ChimeraTK::DoocsAdapter::isInitialised) {
dmsg_info info;
memset(&info, 0, sizeof(info));
info.sec = seconds;
info.usec = microseconds;
auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
info.sec = sinceEpoch.seconds;
info.usec = sinceEpoch.microseconds;
if(_macroPulseNumberSource != nullptr) {
info.ident = _macroPulseNumberSource->accessData(0);
}
......
......@@ -61,13 +61,14 @@ namespace ChimeraTK {
this->d_error(no_error);
}
// Convert time stamp from version number in Unix time (seconds and microseconds).
// Note that epoch of std::chrono::system_time might be different from Unix time, and Unix time omits leap seconds
// and hence is not the duration since the epoch! We have to convert to time_t and then find out the microseconds.
// Convert time stamp from version number to DOOCS timestamp
doocs::Timestamp timestamp(_processScalar->getVersionNumber().getTime());
auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
auto seconds = sinceEpoch.seconds;
auto microseconds = sinceEpoch.microseconds;
// Make sure we never send out two absolute identical time stamps. If we would do so, the "watchdog" which
// corrects inconsistencies in ZeroMQ subscriptions between sender and subcriber cannot detect the inconsistency.
if(this->get_timestamp() == timestamp) {
timestamp += std::chrono::microseconds(1);
}
// update global time stamp of DOOCS, but only if our time stamp is newer
if(get_global_timestamp() < timestamp) {
......@@ -94,15 +95,16 @@ namespace ChimeraTK {
// We must set the timestamp again so it is correctly attached to the variable. set_and_archive does not to it.
// This must happen after set_and_archive, otherwise the global time stamp is taken.
this->set_tmstmp(seconds, microseconds);
this->set_timestamp(timestamp);
if(_macroPulseNumberSource) this->set_mpnum(_macroPulseNumberSource->accessData(0));
// send data via ZeroMQ if enabled and if DOOCS initialisation is complete
if(_publishZMQ && ChimeraTK::DoocsAdapter::isInitialised) {
dmsg_info info;
memset(&info, 0, sizeof(info));
info.sec = seconds;
info.usec = microseconds;
auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
info.sec = sinceEpoch.seconds;
info.usec = sinceEpoch.microseconds;
if(_macroPulseNumberSource != nullptr) {
info.ident = _macroPulseNumberSource->accessData(0);
}
......
......@@ -87,6 +87,12 @@ namespace ChimeraTK {
doocs::Timestamp timestamp(_i1Value->getVersionNumber().getTime());
// Make sure we never send out two absolute identical time stamps. If we would do so, the "watchdog" which
// corrects inconsistencies in ZeroMQ subscriptions between sender and subcriber cannot detect the inconsistency.
if(this->get_timestamp() == timestamp) {
timestamp += std::chrono::microseconds(1);
}
// update global time stamp of DOOCS, but only if our time stamp is newer
if(get_global_timestamp() < timestamp) {
set_global_timestamp(timestamp);
......
......@@ -148,14 +148,18 @@ namespace ChimeraTK {
}
_doocsSuccessfullyUpdated = true;
// Convert time stamp from version number in Unix time (seconds and microseconds).
// Note that epoch of std::chrono::system_time might be different from Unix time, and Unix time omits leap seconds
// and hence is not the duration since the epoch! We have to convert to time_t and then find out the microseconds.
auto timestamp = _processArray->getVersionNumber().getTime();
auto seconds = std::chrono::system_clock::to_time_t(timestamp);
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(
timestamp - std::chrono::system_clock::from_time_t(seconds))
.count();
// Convert time stamp from version number to DOOCS timestamp
doocs::Timestamp timestamp(_processArray->getVersionNumber().getTime());
// Make sure we never send out two absolute identical time stamps. If we would do so, the "watchdog" which
// corrects inconsistencies in ZeroMQ subscriptions between sender and subcriber cannot detect the inconsistency.
if(this->get_timestamp() == timestamp) {
timestamp += std::chrono::microseconds(1);
}
auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
auto seconds = sinceEpoch.seconds;
auto microseconds = sinceEpoch.microseconds;
// set macro pulse number, buffer number and time stamp
size_t ibuf = 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment