Merge "Fix bug 564"
[osm/N2VC.git] / modules / libjuju / juju / utils.py
index 1d9bc1c..3565fd6 100644 (file)
@@ -46,6 +46,7 @@ async def read_ssh_key(loop):
     can be passed on to a model.
 
     '''
+    loop = loop or asyncio.get_event_loop()
     return await loop.run_in_executor(None, _read_ssh_key)
 
 
@@ -71,6 +72,16 @@ class IdQueue:
             await queue.put(value)
 
 
+async def block_until(*conditions, timeout=None, wait_period=0.5, loop=None):
+    """Return only after all conditions are true.
+
+    """
+    async def _block():
+        while not all(c() for c in conditions):
+            await asyncio.sleep(wait_period, loop=loop)
+    await asyncio.wait_for(_block(), timeout, loop=loop)
+
+
 async def run_with_interrupt(task, event, loop=None):
     """
     Awaits a task while allowing it to be interrupted by an `asyncio.Event`.
@@ -91,6 +102,10 @@ async def run_with_interrupt(task, event, loop=None):
                                        return_when=asyncio.FIRST_COMPLETED)
     for f in pending:
         f.cancel()
+    exception = [f.exception() for f in done
+                 if f is not event_task and f.exception()]
+    if exception:
+        raise exception[0]
     result = [f.result() for f in done if f is not event_task]
     if result:
         return result[0]