From: Mark Wooding Date: Sun, 9 May 2010 14:06:18 +0000 (+0100) Subject: python: Better diagnostics for coroutines. X-Git-Tag: 1.0.0pre8~1 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/commitdiff_plain/22b4755242c39bc8e948e4b714bea80433882a11 python: Better diagnostics for coroutines. Provide meaningful names for coroutines, and report switches in the debug output. --- diff --git a/mon/tripemon.in b/mon/tripemon.in index b898ec98..413c8abb 100644 --- a/mon/tripemon.in +++ b/mon/tripemon.in @@ -83,13 +83,15 @@ def invoker(func, *args, **kw): def cr(func, *args, **kw): """Return a function which invokes FUNC(*ARGS, **KW) in a coroutine.""" - def _(*hunoz, **hukairz): - T.Coroutine(xwrap(func)).switch(*args, **kw) - return _ + name = T.funargstr(func, args, kw) + return lambda *hunoz, **hukairz: \ + T.Coroutine(xwrap(func), name = name).switch(*args, **kw) def incr(func): """Decorator: runs its function in a coroutine of its own.""" - return lambda *args, **kw: T.Coroutine(func).switch(*args, **kw) + return lambda *args, **kw: \ + (T.Coroutine(func, name = T.funargstr(func, args, kw)) + .switch(*args, **kw)) ###-------------------------------------------------------------------------- ### Random bits of infrastructure. @@ -1287,7 +1289,8 @@ class PeerWindow (MyWindow): def tryupdate(me): """Start the updater coroutine, if it's not going already.""" if me.cr is None: - me.cr = T.Coroutine(me._update) + me.cr = T.Coroutine(me._update, + name = 'update-peer-window %s' % me.peer.name) me.cr.switch() def stopupdate(me, *hunoz, **hukairz): @@ -1614,7 +1617,8 @@ class MonitorWindow (MyWindow): """ if me._kidding: return - T.Coroutine(me._addautopeer_hack).switch(peer) + T.Coroutine(me._addautopeer_hack, + name = '_addautopeerhack %s' % peer).switch(peer) def _addautopeer_hack(me, peer): """Make an automated connection to PEER in response to a user click.""" diff --git a/py/tripe.py.in b/py/tripe.py.in index 2e21885b..f556bae5 100644 --- a/py/tripe.py.in +++ b/py/tripe.py.in @@ -128,7 +128,9 @@ class Coroutine (_Coroutine): """ def switch(me, *args, **kw): assert _Coroutine.getcurrent() is rootcr + if _debug: print '* %s' % me _Coroutine.switch(me, *args, **kw) + if _debug: print '* %s' % rootcr ###-------------------------------------------------------------------------- ### Default places for things. @@ -610,9 +612,16 @@ def defer(func, *args, **kw): """Call FUNC(*ARGS, **KW) later, in the root coroutine.""" _deferq.append((func, args, kw)) +def funargstr(func, args, kw): + items = [repr(a) for a in args] + for k, v in kw.iteritems(): + items.append('%s = %r' % (k, v)) + return '%s(%s)' % (func.__name__, ', '.join(items)) + def spawn(func, *args, **kw): """Call FUNC, passing ARGS and KW, in a fresh coroutine.""" - defer(lambda: Coroutine(func).switch(*args, **kw)) + defer(lambda: (Coroutine(func, name = funargstr(func, args, kw)) + .switch(*args, **kw))) ## Asides. _asideq = Queue() @@ -702,7 +711,9 @@ class TripeCommandDispatcher (TripeConnection): global _deferq assert _Coroutine.getcurrent() is rootcr - Coroutine(_runasides).switch() + Coroutine(_runasides, name = '_runasides').switch() + if quitp is None: + quitp = me.quitp while not quitp(): while _deferq: q = _deferq diff --git a/svc/conntrack.in b/svc/conntrack.in index 5f4cc98d..eabdc2b1 100644 --- a/svc/conntrack.in +++ b/svc/conntrack.in @@ -457,7 +457,7 @@ def init(): Add the D-Bus monitor here, because we might send commands off immediately, and we want to make sure the server connection is up. """ - T.Coroutine(kickpeers).switch() + T.Coroutine(kickpeers, name = 'kickpeers').switch() dbm = DBusMonitor() dbm.addmon(NetworkManagerMonitor()) dbm.addmon(MaemoICdMonitor()) diff --git a/svc/watch.in b/svc/watch.in index bc904bd9..e058ed8e 100644 --- a/svc/watch.in +++ b/svc/watch.in @@ -614,9 +614,11 @@ def addpeer(info, peer, ifname, *addr): except KeyError: return if 'ifup' in info: - T.Coroutine(ifupdown).switch('ifup', peer, info, ifname, *addr) + T.Coroutine(ifupdown, name = 'ifup %s' % peer) \ + .switch('ifup', peer, info, ifname, *addr) if 'connect' in info: - T.Coroutine(connect).switch(peer, info['connect']) + T.Coroutine(connect, name = 'connect %s' % peer) \ + .switch(peer, info['connect']) if boolean(info, 'watch', False): pinger.add(peer, info, False) @@ -631,7 +633,8 @@ def delpeer(peer): except KeyError: pass if 'ifdown' in info: - T.Coroutine(ifupdown).switch('ifdown', peer, info) + T.Coroutine(ifupdown, name = 'ifdown %s' % peer) \ + .switch('ifdown', peer, info) def notify(_, code, *rest): """ @@ -687,7 +690,7 @@ def init(): errorwatch = ErrorWatch() childwatch = ChildWatch() pinger = Pinger() - T.Coroutine(dbwatch).switch() + T.Coroutine(dbwatch, name = 'dbwatch').switch() errorwatch.switch() pinger.switch()