RIAPS / riaps-pycom

Python implementation of the RIAPS component model
Apache License 2.0
7 stars 8 forks source link

Timer.halt() allows extra timer event #47

Closed timkrentz closed 6 years ago

timkrentz commented 6 years ago

timer.halt() does not work immediately, and allows a subsequent call to on_timer().

Replication: Using /riaps-pycom/test/TimerS/PeriodicTimer.py, add self.periodic.halt() at the end of on_periodic(), like the below:

    def on_periodic(self):
        now = self.periodic.recv_pyobj()                # Receive time (as float)
        self.logger.info('on_periodic():%s',now)
        period = self.periodic.getPeriod()              # Query the period
        if period == 5.0:
            period = period - 1.0
            self.periodic.setPeriod(period)             # Set the period
            self.logger.info('setting period to %f',period)
        msg = now
        self.ticker.send_pyobj(msg)
        self.periodic.halt()

Then run the app with the RIAPS control GUI. I got the below output:

riaps@bbb-1f82:~$ riaps_deplo -n 100.0.0.132
Starting RIAPS DISCOVERY SERVICE 
 * 100.0.0.133
 * b0d5cc831f82
Start DHT node.
DHT node started.
Stored ips: 100.0.0.133; 
Register actor with PID - 7223 : /TimerS/TimerActor/
Get: /TimerS/Tick/pubb0d5cc831f82
Register service: /TimerS/Tick/pubb0d5cc831f82
Changes sent to discovery service: /TimerS/Tick/pubb0d5cc831f82
Search for registered actor: /TimerS/TimerActor/
Port update sent to the client: /TimerS/TimerActor/
INFO:19:25:46,980:PeriodicTimer:on_periodic():1506972346.97926
INFO:19:25:46,989:PeriodicTimer:setting period to 4.000000
INFO:19:25:46,993:SporadicTimer:on_ticker():1506972346.97926
INFO:19:25:47,999:SporadicTimer:on_sporadic() 1506972347.9981887
INFO:19:25:51,981:PeriodicTimer:on_periodic():1506972351.9804168
INFO:19:25:51,985:SporadicTimer:on_ticker():1506972351.9804168
INFO:19:25:51,990:SporadicTimer:canceling sporadic

Notice the two logger messages from on_periodic() five seconds apart, even though self.periodic.halt() was (or should have been) called at the end of the first on_periodic() call. From here, the app logged nothing, implying that the periodic timer was then halted.

timkrentz commented 6 years ago

Can we safely flip lines 42 and 43 in timPort.py? Thus executing the wait before checking the 'started' event. This way, when halt() clears the "started" threading event during a wait, the halt() will interrupt the current clock interval

imadari commented 6 years ago

I would suggest to check the started flag before sending the message:

if self.active.is_set() and self.started.is_set():