aboutsummaryrefslogtreecommitdiff
path: root/rpki/async.py
diff options
context:
space:
mode:
Diffstat (limited to 'rpki/async.py')
-rw-r--r--rpki/async.py79
1 files changed, 14 insertions, 65 deletions
diff --git a/rpki/async.py b/rpki/async.py
index 75b4b656..74143bd1 100644
--- a/rpki/async.py
+++ b/rpki/async.py
@@ -131,6 +131,7 @@ class timer(object):
"""
Debug logging.
"""
+
if self.gc_debug:
bt = traceback.extract_stack(limit = 3)
logger.debug("%s from %s:%d", msg, bt[0][0], bt[0][1])
@@ -140,6 +141,7 @@ class timer(object):
Set a timer. Argument can be a datetime, to specify an absolute
time, or a timedelta, to specify an offset time.
"""
+
if self.gc_debug:
self.trace("Setting %r to %r" % (self, when))
if isinstance(when, rpki.sundial.timedelta):
@@ -162,6 +164,7 @@ class timer(object):
"""
Cancel a timer, if it was set.
"""
+
if self.gc_debug:
self.trace("Canceling %r" % self)
try:
@@ -174,6 +177,7 @@ class timer(object):
"""
Test whether this timer is currently set.
"""
+
return self in timer_queue
def set_handler(self, handler):
@@ -184,12 +188,14 @@ class timer(object):
bound method to an object in a class representing a network
connection).
"""
+
self.handler = handler
def set_errback(self, errback):
"""
Set a timer's errback. Like set_handler(), for errbacks.
"""
+
self.errback = errback
@classmethod
@@ -202,6 +208,7 @@ class timer(object):
called, so that even if new events keep getting scheduled, we'll
return to the I/O loop reasonably quickly.
"""
+
now = rpki.sundial.now()
while timer_queue and now >= timer_queue[0].when:
t = timer_queue.pop(0)
@@ -233,6 +240,7 @@ class timer(object):
the same units (argh!), and we're not doing anything that
hair-triggered, so rounding up is simplest.
"""
+
if not timer_queue:
return None
now = rpki.sundial.now()
@@ -251,6 +259,7 @@ class timer(object):
queue content, but this way we can notify subclasses that provide
their own cancel() method.
"""
+
while timer_queue:
timer_queue.pop(0).cancel()
@@ -258,12 +267,14 @@ def _raiseExitNow(signum, frame):
"""
Signal handler for event_loop().
"""
+
raise ExitNow
def exit_event_loop():
"""
Force exit from event_loop().
"""
+
raise ExitNow
def event_defer(handler, delay = rpki.sundial.timedelta(seconds = 0)):
@@ -271,6 +282,7 @@ def event_defer(handler, delay = rpki.sundial.timedelta(seconds = 0)):
Use a near-term (default: zero interval) timer to schedule an event
to run after letting the I/O system have a turn.
"""
+
timer(handler).set(delay)
## @var debug_event_timing
@@ -282,6 +294,7 @@ def event_loop(catch_signals = (signal.SIGINT, signal.SIGTERM)):
"""
Replacement for asyncore.loop(), adding timer and signal support.
"""
+
old_signal_handlers = {}
while True:
save_sigs = len(old_signal_handlers) == 0
@@ -323,71 +336,6 @@ def event_loop(catch_signals = (signal.SIGINT, signal.SIGTERM)):
for sig in old_signal_handlers:
signal.signal(sig, old_signal_handlers[sig])
-class sync_wrapper(object):
- """
- Synchronous wrapper around asynchronous functions. Running in
- asynchronous mode at all times makes sense for event-driven daemons,
- but is kind of tedious for simple scripts, hence this wrapper.
-
- The wrapped function should take at least two arguments: a callback
- function and an errback function. If any arguments are passed to
- the wrapper, they will be passed as additional arguments to the
- wrapped function.
- """
-
- res = None
- err = None
- fin = False
-
- def __init__(self, func, disable_signal_handlers = False):
- self.func = func
- self.disable_signal_handlers = disable_signal_handlers
-
- def cb(self, res = None):
- """
- Wrapped code has requested normal termination. Store result, and
- exit the event loop.
- """
- self.res = res
- self.fin = True
- logger.debug("%r callback with result %r", self, self.res)
- raise ExitNow
-
- def eb(self, err):
- """
- Wrapped code raised an exception. Store exception data, then exit
- the event loop.
- """
- exc_info = sys.exc_info()
- self.err = exc_info if exc_info[1] is err else err
- self.fin = True
- logger.debug("%r errback with exception %r", self, self.err)
- raise ExitNow
-
- def __call__(self, *args, **kwargs):
-
- def thunk():
- try:
- self.func(self.cb, self.eb, *args, **kwargs)
- except ExitNow:
- raise
- except Exception, e:
- self.eb(e)
-
- event_defer(thunk)
- if self.disable_signal_handlers:
- event_loop(catch_signals = ())
- else:
- event_loop()
- if not self.fin:
- logger.warning("%r event_loop terminated without callback or errback", self)
- if self.err is None:
- return self.res
- elif isinstance(self.err, tuple):
- raise self.err[0], self.err[1], self.err[2]
- else:
- raise self.err
-
class gc_summary(object):
"""
Periodic summary of GC state, for tracking down memory bloat.
@@ -405,6 +353,7 @@ class gc_summary(object):
"""
Collect and log GC state for this period, reset timer.
"""
+
logger.debug("gc_summary: Running gc.collect()")
gc.collect()
logger.debug("gc_summary: Summarizing (threshold %d)", self.threshold)