def makeTSServerObjects(tsServer, wallClock, timelineSelector, tickRate, startTickValue): """\ create a clock with tick rate, and correlated with wall clock to be paused at the intended start value. create a time line source, that uses the wall clock and timeline clock for creating time stamps to be sent by the TS server on demand of the harness (by calling sendTSMessage). attach that time line to the TS server. No messages are sent over TS protocol until client(s) are connected, and only then when sendTSMessage() is called by the harness """ syncClock = CorrelatedClock(parentClock=wallClock, tickRate=tickRate) syncClock.speed = 0 syncClock.correlation = (wallClock.ticks, startTickValue) pauseSyncTimelineClock(syncClock) # Once added to the TS server, the timeline is available for clients to request via the server # for TS messages from this type of timeline, if it exists for the CI stem sent by the TS client. # normally this CI stem matches a substring of the CII-delivered contentId. syncTimelineSrc = SimpleClockTimelineSource( timelineSelector=timelineSelector, wallClock=wallClock, clock=syncClock) tsServer.attachTimelineSource(syncTimelineSrc) return syncClock
def algorithm(self): candidateClock = CorrelatedClock(self.clock.getParent(), tickRate=self.clock.tickRate, correlation=self.clock.correlation) while True: update = False cumulativeOffset = None candidate = (yield self.timeoutSecs) t = self.clock.ticks currentDispersion = self.clock.dispersionAtTime(t) if candidate is not None: candidateClock.correlation = candidate.calcCorrelationFor( self.clock, self.localMaxFreqErrorPpm) candidateDispersion = candidateClock.dispersionAtTime(t) update = candidateDispersion < currentDispersion if update: pt = self.clock.toParentTicks(t) adjustment = candidateClock.fromParentTicks(pt) - t if cumulativeOffset is None: cumulativeOffset = 0 else: cumulativeOffset += adjustment self.clock.correlation = candidateClock.correlation self.onClockAdjusted( self.clock.ticks, adjustment, 1000000000 * currentDispersion, 1000000000 * candidateDispersion, self.clock.correlation.errorGrowthRate) else: pass # update worst dispersion seen so far self.worstDispersion = max(self.worstDispersion, currentDispersion, candidateDispersion) co = cumulativeOffset or 0 # convert None to 0 self.log.info( "Old / New dispersion (millis) is %.5f / %.5f ... offset=%20d new best candidate? %s\n" % (1000 * currentDispersion, 1000 * candidateDispersion, co, str(update))) else: self.log.info("Timeout. Dispersion (millis) is %.5f\n" % (1000 * currentDispersion, )) # retry more quickly if we didn't get an improved candidate if update: time.sleep(self.repeatSecs) else: time.sleep(self.timeoutSecs)
def test_changeCorrelation(self): mockTime = self.mockTime mockTime.timeNow = 5020.8 b = SysClock() c = CorrelatedClock(b, 1000, correlation=(0,300)) self.assertAlmostEqual(c.ticks, 5020.8*1000 + 300, places=5) c.correlation = (50000,320) self.assertEqual(c.correlation, (50000,320)) self.assertAlmostEqual(c.ticks, (int(5020.8*1000000) - 50000) / 1000 + 320, places=5)
def test_changeCorrelation(self): mockTime = self.mockTime b = self.newSysClock() mockTime.timeNow = 5020.8 c = CorrelatedClock(b, 1000, correlation=Correlation(0, 300)) self.assertAlmostEqual(c.ticks, 5020.8 * 1000 + 300, places=5) c.correlation = Correlation(50000, 320) self.assertEqual(c.correlation, Correlation(50000, 320)) self.assertAlmostEqual(c.ticks, (int(5020.8 * 1000000) - 50000) / 1000 + 320, places=5)
def test_changeCorrelationNotifies(self): """Check a change to the correlation propagates notifications to dependents of this clock""" b = self.newSysClock() c = CorrelatedClock(b, 1000, correlation=Correlation(0, 300)) cc = CorrelatedClock(c, 50) d1 = MockDependent() d2 = MockDependent() d3 = MockDependent() b.bind(d1) c.bind(d2) cc.bind(d3) c.correlation = Correlation(50, 20) d1.assertNotNotified() d2.assertNotificationsEqual([c]) d3.assertNotificationsEqual([cc])
def test_changeCorrelationNotifies(self): """Check a change to the correlation propagates notifications to dependents of this clock""" b = SysClock() c = CorrelatedClock(b, 1000, correlation=(0,300)) cc = CorrelatedClock(c, 50) d1 = MockDependent() d2 = MockDependent() d3 = MockDependent() b.bind(d1) c.bind(d2) cc.bind(d3) c.correlation = (50,20) d1.assertNotNotified() d2.assertNotificationsEqual([c]) d3.assertNotificationsEqual([cc])