diff options
Diffstat (limited to 'testing/tests/responsiveness/watchdog.py')
-rw-r--r-- | testing/tests/responsiveness/watchdog.py | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/testing/tests/responsiveness/watchdog.py b/testing/tests/responsiveness/watchdog.py new file mode 100644 index 00000000..88f4fa67 --- /dev/null +++ b/testing/tests/responsiveness/watchdog.py @@ -0,0 +1,53 @@ +from twisted.internet import defer, reactor +from twisted.internet.task import LoopingCall +from twisted.internet.threads import deferToThread + + +class Watchdog(object): + + DEBUG = False + + def __init__(self, delay=0.01): + self.delay = delay + self.loop_call = LoopingCall.withCount(self.watch) + self.blocked = 0 + self.checks = [] + self.d = None + + def start(self): + self.debug("\n[watchdog] starting") + self.loop_call.start(self.delay) + self.d = defer.Deferred() + return self.d + + def watch(self, count): + self.debug("[watchdog] watching (%d)" % count) + if (self.loop_call.running): + self.checks.append(deferToThread(self._check, count)) + + def _check(self, count): + # self.debug("[watchdog] _checking (%d)" % count) + if count > 1: + self.blocked += count + + def stop(self): + # delay the actual stop so we make sure at least one check watch will + # run in the reactor. + reactor.callLater(2 * self.delay, self._stop) + + @defer.inlineCallbacks + def _stop(self): + if not self.loop_call.running: + return + + self.loop_call.stop() + yield defer.gatherResults(self.checks) + self.d.callback(None) + + @property + def seconds_blocked(self): + return self.blocked * self.delay + + def debug(self, s): + if self.DEBUG: + print(s) |