fastdds qos:LifespanQosPolicy
在实际业务中,如果对数据的新/旧程度有要求,比如数据产生之后如果1ms都没有被使用,那么数据就相当于过期了,没有使用价值了,这种数据直接丢弃就可以了。如果有这种需求,那么可以考虑结合LifespanQosPolicy来实现。
(1)当DataWriter写数据History的数据,或者接收数据到DataReader的History的数据,均可以加时间戳
DataWriter侧写sourceTimestamp:
bool WriterHistory::prepare_and_add_change(
CacheChange_t* a_change,
WriteParams& wparams)
{
...
a_change->sourceTimestamp = wparams.source_timestamp();
...
}
数据接收侧写sourceTimestamp:
bool MessageReceiver::proc_Submsg_DataFrag(
CDRMessage_t* msg,
SubmessageHeader_t* smh,
bool was_decoded) const
{
...
if (have_timestamp_)
{
ch.sourceTimestamp = timestamp_;
}
...
}
(2)定时器
如果DataWriter或者DataReader使能了LifespanQosPolicy时,那么便会创建定时器来监督是不是有数据超时。
如下是DataWriter创建定时器的代码:
lifespan_timer_ = new TimedEvent(publisher_->rtps_participant()->get_resource_event(),
[&]() -> bool
{
return lifespan_expired();
},
qos_.lifespan().duration.to_ns() * 1e-6);
在函数lifespan_expired中判断如果有数据超时,便会通过函数remove_change_pub将数据移出。
bool DataWriterImpl::lifespan_expired()
{
while (history_->get_earliest_change(&earliest_change))
{
if (now - source_timestamp < lifespan_duration_us_)
{
auto interval = source_timestamp - now + lifespan_duration_us_;
lifespan_timer_->update_interval_millisec(static_cast<double>(duration_cast<milliseconds>(interval).count()));
return true;
}
// The earliest change has expired
history_->remove_change_pub(earliest_change);
}
(3)example测试
通过helloworld进行测试,将超时时间设置的非常短100ns,实际测试可以看到DataReader接收不到DataWriter发送的数据。
writer_qos.lifespan().duration = eprosima::fastdds::dds::Duration_t(0,100);
reader_qos.lifespan().duration = eprosima::fastdds::dds::Duration_t(0,100);
默认情况下,lifespan qos策略不生效,也就是在History中的数据不存在超时的情况。