2

Is there a non-blocking way to wait or come back to this function within twisted?

I have a loop ticker that is just set to tick on a set interval and that is all working GREAT. However, when stopping it I want to make sure that it isn't currently in a Tick doing any work. If it is I just want twisted to come back to it and kill it in a moment.

def stop(self):
    import time
    while self.in_tick:
        time.sleep(.001) # Blocking
    self.active = False
    self.reset()
    self.timer.stop()

Sometimes this above function gets called while another thread is running a Tick operation and I want to finish the Tick and then come back and stop this.

I DO NOT want to block the loop in anyway during this operation. How could I do so?

Jared Mackey
  • 3,998
  • 4
  • 31
  • 50

1 Answers1

0

It looks a bit strange to do a time.sleep() instead of just waiting for an event to signal and fire a deferred to do what you want. With threads you might wake up this thread, check 'self.in_tick == False' and before you reach 'self.active = False', the other thread starts the new tick, so this might have a race condition and may not work as you expect anyway. So hopefully you have some other thread synchronization somewhere to make it work.

You can try to split your code into two functions and have one that schedules itself if not done.

def stop(self):
    # avoid reentracy
    if not self._stop_call_running:
        self._stop()

def _stop(self):
    if self.in_tick:
       # reschedule itself
       self._stop_call_running = reactor.callLater(0.001, self._stop)
       return
    self.active = False
    self.reset()
    self.timer.stop()
    self._stop_call_running = None

You might also look at twisted.internet.task.LoopingCall.

schlenk
  • 7,002
  • 1
  • 25
  • 29