dog = .WatchDog~new(1) -- watchdog with 1 sec time-out
say dog~watchTask(.task~new~start("runsLong", 0.5))
say dog~watchTask(.task~new~start("runsLong", 1.5))
::class Task
-- a long-running task that we may want to terminate early
::method runsLong
use strict arg seconds
signal on halt
do s = 0 to seconds by 0.1 -- split SysSleep to enable halting
call SysSleep 0.1 -- do "hard work"
end
return "task finished"
halt:
return condition("DESCRIPTION") -- return description from halt()
::class Watchdog inherit AlarmNotification
-- sets a time-out, after which a running task will be halted
::method init
expose timeOut
use strict arg timeOut
-- watches over a task, halting it if it runs too long
::method watchTask
expose timeOut
use strict arg message
-- we set an Alarm for 'timeOut' seconds, which, upon triggering
-- will call method triggered(), passing this Alarm object as an argument
-- (this is why we inherit from AlarmNotification)
-- we also attach 'message' to enable triggered() to halt the task
alarm = .Alarm~new(timeOut, self, message)
-- now we just wait for 'message' to finish; either normally, or halted
msgResult = message~result
alarm~cancel -- cancel alarm; may still be active
return msgResult
::method triggered unguarded
expose timeOut
-- our watchTask Alarm has triggered
-- this means that the task has run too long
use arg alarm
message = alarm~attachment -- message is our attachment
message~halt("task took longer than" timeOut "sec")