chiark / gitweb /
python: Better diagnostics for coroutines.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 9 May 2010 14:06:18 +0000 (15:06 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 9 May 2010 14:23:56 +0000 (15:23 +0100)
Provide meaningful names for coroutines, and report switches in the
debug output.

mon/tripemon.in
py/tripe.py.in
svc/conntrack.in
svc/watch.in

index b898ec98721fea08c2fbb8a6451f4a596edf01d1..413c8abbf531fd41955ca455846b06b96b076acc 100644 (file)
@@ -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."""
index 2e21885b8797ba7e18c3a4af009ffd0a41d3a36a..f556bae53f424ecbd8d3f130040abfcff5aa6c5f 100644 (file)
@@ -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
index 5f4cc98d8ef7b0acde836d054c4a9d54e1645ca8..eabdc2b114a0de2350da5e017bdec181e4e12426 100644 (file)
@@ -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())
index bc904bd904582cc5d12e72f308c263a5ea405ffd..e058ed8e7db17fa98d4c2b098c239ec73d980389 100644 (file)
@@ -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()