1074
1073
def __del__(self):
1077
def init_checker(self):
1078
# Schedule a new checker to be started an 'interval' from now,
1079
# and every interval from then on.
1076
def init_checker(self, randomize_start=False):
1077
# Schedule a new checker to be started a randomly selected
1078
# time (a fraction of 'interval') from now. This spreads out
1079
# the startup of checkers over time when the server is
1080
1081
if self.checker_initiator_tag is not None:
1081
1082
GLib.source_remove(self.checker_initiator_tag)
1083
interval_milliseconds = int(self.interval.total_seconds()
1086
delay_milliseconds = random.randrange(
1087
interval_milliseconds + 1)
1089
delay_milliseconds = interval_milliseconds
1082
1090
self.checker_initiator_tag = GLib.timeout_add(
1083
random.randrange(int(self.interval.total_seconds() * 1000
1086
# Schedule a disable() when 'timeout' has passed
1091
delay_milliseconds, self.start_checker, randomize_start)
1092
delay = datetime.timedelta(0, 0, 0, delay_milliseconds)
1093
# A checker might take up to an 'interval' of time, so we can
1094
# expire at the soonest one interval after a checker was
1095
# started. Since the initial checker is delayed, the expire
1096
# time might have to be extended.
1097
now = datetime.datetime.utcnow()
1098
self.expires = now + delay + self.interval
1099
# Schedule a disable() at expire time
1087
1100
if self.disable_initiator_tag is not None:
1088
1101
GLib.source_remove(self.disable_initiator_tag)
1089
1102
self.disable_initiator_tag = GLib.timeout_add(
1090
int(self.timeout.total_seconds() * 1000), self.disable)
1091
# Also start a new checker *right now*.
1092
self.start_checker()
1103
int((self.expires - now).total_seconds() * 1000),
1094
1106
def checker_callback(self, source, condition, connection,
1138
1150
def need_approval(self):
1139
1151
self.last_approval_request = datetime.datetime.utcnow()
1141
def start_checker(self):
1153
def start_checker(self, start_was_randomized=False):
1142
1154
"""Start a new checker subprocess if one is not running.
1144
1156
If a checker already exists, leave it running and do
1194
1206
GLib.IOChannel.unix_new(pipe[0].fileno()),
1195
1207
GLib.PRIORITY_DEFAULT, GLib.IO_IN,
1196
1208
self.checker_callback, pipe[0], command)
1209
if start_was_randomized:
1210
# We were started after a random delay; Schedule a new
1211
# checker to be started an 'interval' from now, and every
1212
# interval from then on.
1213
now = datetime.datetime.utcnow()
1214
self.checker_initiator_tag = GLib.timeout_add(
1215
int(self.interval.total_seconds() * 1000),
1217
self.expires = max(self.expires, now + self.interval)
1218
# Don't start a new checker again after same random delay
1197
1220
# Re-run this periodically if run by GLib.timeout_add