-
-
Save wonderbeyond/f2eb849d1e5f024a88508b60db376b49 to your computer and use it in GitHub Desktop.
Revisions
-
wonderbeyond revised this gist
Nov 23, 2022 . 1 changed file with 12 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,12 +2,22 @@ import asyncio def get_event_loop(): try: return asyncio.get_event_loop() except RuntimeError as e: if "There is no current event loop in thread" in str(e): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) return asyncio.get_event_loop() raise def force_async(fn): ''' turns a sync function to async function using threads ''' from concurrent.futures import ThreadPoolExecutor pool = ThreadPoolExecutor() @wraps(fn) @@ -22,13 +32,9 @@ def force_sync(fn): ''' turn an async function to sync function ''' @wraps(fn) def wrapper(*args, **kwargs): res = fn(*args, **kwargs) return get_event_loop().run_until_complete(res) if asyncio.iscoroutine(res) else res return wrapper -
wonderbeyond revised this gist
Nov 22, 2022 . 1 changed file with 8 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,5 @@ from functools import wraps import asyncio def force_async(fn): @@ -9,7 +10,7 @@ def force_async(fn): import asyncio pool = ThreadPoolExecutor() @wraps(fn) def wrapper(*args, **kwargs): future = pool.submit(fn, *args, **kwargs) return asyncio.wrap_future(future) # make it awaitable @@ -21,13 +22,13 @@ def force_sync(fn): ''' turn an async function to sync function ''' if not hasattr(force_sync, '_event_loop'): force_sync._event_loop = asyncio.new_event_loop() loop = force_sync._event_loop @wraps(fn) def wrapper(*args, **kwargs): res = fn(*args, **kwargs) return loop.run_until_complete(res) if asyncio.iscoroutine(res) else res return wrapper -
konpatp revised this gist
Feb 3, 2017 . 1 changed file with 3 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -30,15 +30,16 @@ def test(): @force_sync async def main(): import asyncio # if it were to execute sequentially, it would take 10 seconds, in this case we expect to see only 1 second futures = list(map(lambda x: test(), range(10))) return await asyncio.gather(*futures) import time # take the elapsed time start = time.time() res = main() end = time.time() elapsed = end - start self.assertEqual(len(res), 10) self.assertLess(elapsed, 1.2) # a little more than 1 second is normal -
konpatp revised this gist
Feb 3, 2017 . 1 changed file with 44 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,11 +1,44 @@ import unittest from async import * class AsyncCanTurnAsyncIntoSyncFunction(unittest.TestCase): def test_turn_async_to_sync(self): @force_sync async def test(): import asyncio await asyncio.sleep(0.1) return 1 + 2 self.assertEqual(test(), 3) def test_turn_sync_to_sync(self): @force_sync def test(): return 1 + 2 self.assertEqual(test(), 3) class AsyncCanTurnSyncIntoAsyncFunction(unittest.TestCase): def test_turn_sync_to_async(self): @force_async def test(): import time time.sleep(1) return True @force_sync async def main(): import asyncio futures = list(map(lambda x: test(), range(10))) return await asyncio.gather(*futures) import time start = time.time() res = main() end = time.time() elapsed = end - start self.assertEqual(len(res), 10) self.assertLess(elapsed, 1.2) -
konpatp revised this gist
Feb 3, 2017 . 1 changed file with 26 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,10 +1,33 @@ import functools def force_async(fn): ''' turns a sync function to async function using threads ''' from concurrent.futures import ThreadPoolExecutor import asyncio pool = ThreadPoolExecutor() @functools.wraps(fn) def wrapper(*args, **kwargs): future = pool.submit(fn, *args, **kwargs) return asyncio.wrap_future(future) # make it awaitable return wrapper def force_sync(fn): ''' turn an async function to sync function ''' import asyncio @functools.wraps(fn) def wrapper(*args, **kwargs): res = fn(*args, **kwargs) if asyncio.iscoroutine(res): return asyncio.get_event_loop().run_until_complete(res) return res return wrapper -
konpatp revised this gist
Feb 3, 2017 . 1 changed file with 11 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,11 @@ @force_async def long_blocking_function(): import time time.sleep(10) return True import asyncio async def run(): a = long_blocking_function() b = long_blocking_function() return await asyncio.gather(a, b) # [True, True] in 10 seconds -
konpatp created this gist
Feb 3, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,10 @@ def async(fn): from concurrent.futures import ThreadPoolExecutor import asyncio pool = ThreadPoolExecutor() def wrapper(*args, **kwargs) -> asyncio.Future: future = pool.submit(fn, *args, **kwargs) return asyncio.wrap_future(future) # make it awaitable return wrapper