@@ -116,6 +116,10 @@ private:
116116 bool firstData_;
117117 Time previousStartTime_;
118118
119+ // Placeholder for latest sync time in case we were able to fetch a sync time
120+ // but the data port reported OOD. We re-use the same sync time but re-fetch the data.
121+ DataPtr<Timestamp> interpolationTime_;
122+
119123private:
120124 void reset ();
121125
@@ -168,13 +172,18 @@ public:
168172 return Algorithm::name ();
169173 }
170174 WeakSynchronizationNode (const Core::Configuration& c)
171- : Core::Component(c), Precursor(c) {}
175+ : Core::Component(c),
176+ Precursor (c) {}
172177 virtual ~WeakSynchronizationNode () {}
173178};
174179
175180template <class Algorithm >
176181SynchronizationNode<Algorithm>::SynchronizationNode(const Core::Configuration& c)
177- : Core::Component(c), Node(c), firstData_(true ), previousStartTime_(Core::Type<Time>::min) {
182+ : Core::Component(c),
183+ Node (c),
184+ firstData_(true ),
185+ previousStartTime_(Core::Type<Time>::min),
186+ interpolationTime_() {
178187 ignoreErrors_ = paramSynchronizationIgnoreErrors (c);
179188
180189 addInputs (2 );
@@ -208,35 +217,51 @@ bool SynchronizationNode<Algorithm>::configure() {
208217
209218template <class Algorithm >
210219bool SynchronizationNode<Algorithm>::work(Flow::PortId p) {
211- DataPtr<Timestamp> interpolationTime;
212- if (!getData (1 , interpolationTime)) {
213- putData (0 , interpolationTime.get ());
214- putData (1 , interpolationTime.get ());
215- return true ;
220+ if (!interpolationTime_) {
221+ if (!getData (1 , interpolationTime_)) {
222+ verify (Flow::Data::isSentinel (interpolationTime_.get ()));
223+ putData (0 , interpolationTime_.get ());
224+ putData (1 , interpolationTime_.get ());
225+ interpolationTime_.reset ();
226+ return interpolationTime_.get () != Flow::Data::ood ();
227+ }
216228 }
217229
218230 DataPointer out;
219- if (Algorithm::work (*interpolationTime , out)) {
231+ if (Algorithm::work (*interpolationTime_ , out)) {
220232 verify ((bool )out);
221233 putData (0 , out.get ());
222- putData (1 , interpolationTime.get ());
234+ putData (1 , interpolationTime_.get ());
235+ interpolationTime_.reset ();
223236 return true ;
224237 }
225238
226- if (!ignoreErrors_)
239+ verify (Flow::Data::isSentinel (out.get ()));
240+ if (out == Flow::Data::ood ()) {
241+ // forward OOD
242+ putData (0 , out.get ());
243+ putData (1 , out.get ());
244+ return false ;
245+ }
246+
247+ if (!ignoreErrors_) {
227248 this ->criticalError (" %s" , this ->lastError ().c_str ());
249+ }
250+
228251 // Synchronization failed, typically at the end of the segment, so put eos
229252 putData (0 , Flow::Data::eos ());
230- putData (1 , interpolationTime.get ());
253+ putData (1 , interpolationTime_.get ());
254+ interpolationTime_.reset ();
231255 return true ;
232256}
233257
234258template <class Algorithm >
235259bool SynchronizationNode<Algorithm>::nextData(DataPointer& dataPointer) {
236260 bool result = Node::getData (0 , dataPointer);
237261 if (result) {
238- if (!dataPointer)
262+ if (!dataPointer) {
239263 criticalError (" Input is null." );
264+ }
240265
241266 if (!firstData_ &&
242267 !Core::isSignificantlyLess (previousStartTime_, dataPointer->startTime (), timeTolerance)) {
@@ -247,9 +272,11 @@ bool SynchronizationNode<Algorithm>::nextData(DataPointer& dataPointer) {
247272 firstData_ = false ;
248273 previousStartTime_ = dataPointer->startTime ();
249274 }
250- else {
251- if (firstData_)
252- warning (" Input stream is empty." );
275+ else if (dataPointer == Flow::Data::ood ()) {
276+ return result;
277+ }
278+ else if (firstData_) {
279+ warning (" Input stream is empty." );
253280 }
254281 return result;
255282}
@@ -267,6 +294,7 @@ void SynchronizationNode<Algorithm>::reset() {
267294 Algorithm::reset ();
268295 firstData_ = true ;
269296 previousStartTime_ = Core::Type<Time>::min;
297+ interpolationTime_.reset ();
270298}
271299
272300} // namespace Flow
0 commit comments