Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

twisted loopingcall not calling errback

I've been writing a few Twisted servers and have created a WatchDog timer that runs periodically. It's default behavior is to check if it was called within some delta of time from it's schedule, which helps to report if the program is being blocked unduly. It also provides a way for a user defined callback function to the WatchDog that could be used to check the health of other parts of the system. The WatchDog timer is implemented using the twisted.internet.task.LoopingCall. I'm concerned if the user defined function creates an exception the WatchDog timer will stop being called. I have Exception handling in the code, but I'd like to have a way to restart the WatchDog timer if it should still manage to crash. However, I don't understand how to use the deferred returned by the LoopingCall().start() method. Here's some sample code to show what I mean:

import sys
from twisted.internet import reactor, defer, task
from twisted.python import log

def periodic_task():
    log.msg("periodic task running")
    x = 10 / 0

def periodic_task_crashed():
    log.msg("periodic_task broken")

log.startLogging(sys.stdout)

my_task = task.LoopingCall(periodic_task)
d = my_task.start(1)
d.addErrback(periodic_task_crashed)
reactor.run()

When I run this code I get one "periodic task running" message from the periodic_task() function and that's it. The deferred returned by my_task.start(1) never has it's errback called, which by my reading of the documentation is what's supposed to happen.

Can someone help me out and point me to what I'm doing wrong?

Thanks in advance! Doug

like image 773
writes_on Avatar asked Oct 18 '25 20:10

writes_on


1 Answers

The signature of periodic_task_crashed is wrong. It is an error callback on a Deferred, so it will be called with an argument, the Failure representing the error result the Deferred got. Since it is defined to take no arguments, calling it produces a TypeError which becomes the new error result of the Deferred.

Redefine it like this:

def periodic_task_crashed(reason):
    log.err(reason, "periodic_task broken")
like image 191
Jean-Paul Calderone Avatar answered Oct 20 '25 10:10

Jean-Paul Calderone



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!