Navigation Menu

Skip to content

Commit

Permalink
fix: async_run to allow nested event loops. (#1170)
Browse files Browse the repository at this point in the history
* Fix async_run to allow nested event loops.

Fixes: #1105

* Use standard asyncio.run in outer loop for tests
  • Loading branch information
ashwinvis committed Sep 24, 2021
1 parent 41a5071 commit 5dc6bbd
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
18 changes: 17 additions & 1 deletion snakemake/common/__init__.py
Expand Up @@ -37,7 +37,23 @@ def async_run(coroutine):


else:
async_run = asyncio.run

def async_run(coroutine):
"""Attaches to running event loop or creates a new one to execute a
coroutine.
.. seealso::
https://github.com/snakemake/snakemake/issues/1105
https://stackoverflow.com/a/65696398
"""
try:
_ = asyncio.get_running_loop()
except RuntimeError:
asyncio.run(coroutine)
else:
asyncio.create_task(coroutine)


# A string that prints as TBD
Expand Down
25 changes: 25 additions & 0 deletions tests/testapi.py
Expand Up @@ -2,6 +2,8 @@
Tests for Snakemake’s API
"""
from snakemake import snakemake
import asyncio
import sys
import tempfile
import os.path
from textwrap import dedent
Expand Down Expand Up @@ -32,3 +34,26 @@ def test_run_script_directive():
file=f,
)
snakemake(path, workdir=tmpdir)


def test_run_script_directive_async():
"""Tests :func`snakemake.common.async_run`. The test ensure the ability to
execute Snakemake API even if an asyncio event loop is already running.
"""
import tracemalloc
from snakemake.common import async_run

tracemalloc.start()

async def dummy_task():
await asyncio.sleep(0.00001)

async def main():
async_run(dummy_task())
test_run_script_directive()

if sys.version_info < (3, 7):
async_run(main())
else:
asyncio.run(main())

0 comments on commit 5dc6bbd

Please sign in to comment.