Created
February 4, 2023 00:09
-
-
Save pwtail/2bbf0f122ddb9d5b70bc6e3db4e8d0ab to your computer and use it in GitHub Desktop.
For django forum
This file contains 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 characters
import asyncio | |
import threading | |
import time | |
from asyncio import get_event_loop | |
from functools import wraps | |
from concurrent.futures import ThreadPoolExecutor | |
# implemented for fun. Could use asriref | |
def sync_to_async(f): | |
@wraps(f) | |
def wrapper(*args, **kw): | |
fut = pool.submit(f, *args, **kw) | |
loop = get_event_loop() | |
a_fut = asyncio.Future() | |
def on_done(fut): | |
loop.call_soon_threadsafe(a_fut.set_result, fut.result()) | |
fut.add_done_callback(on_done) | |
return a_fut | |
return wrapper | |
def wrap_outer(co_func): | |
@wraps(co_func) | |
async def wrapper(*args, **kwargs): | |
gen = co_func(*args, **kwargs) | |
val = None | |
@sync_to_async | |
def fun(val=val): | |
try: | |
return gen.send(val) | |
except StopIteration as ex: | |
return ex.value | |
fut = fun() | |
val = await fut | |
assert val == 'start' | |
def g1(val=val): | |
val = gen.send(val) | |
while val != 'end': | |
yield val | |
val = gen.send(val) | |
await asyncio.create_task(g1()) | |
@sync_to_async | |
def fun2(val=val): | |
try: | |
return gen.send(val) | |
except StopIteration as ex: | |
return ex.value | |
val = await fun2() | |
return val | |
return wrapper | |
class Start: | |
def __await__(self): | |
yielded = yield 'start' | |
assert yielded == 'start' | |
class End: | |
def __await__(self): | |
yield 'end' | |
class IO: | |
def __aenter__(self): | |
return Start() | |
def __aexit__(self, exc_type, exc_val, exc_tb): | |
return End() | |
io = IO() | |
if __name__ == '__main__': | |
async def main(): | |
time.sleep(0.5) | |
print(threading.get_ident()) | |
async with io: | |
await asyncio.sleep(0.5) | |
print(threading.get_ident()) | |
time.sleep(0.5) | |
print(threading.get_ident()) | |
return 0.5 | |
async def other(): | |
return await main() | |
@wrap_outer | |
async def outer(): | |
val = await other() | |
print(val) | |
pool = ThreadPoolExecutor(max_workers=5) | |
with pool: | |
asyncio.run(outer()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment