forked from goodboy/tractor
				
			Move asyncio guest mode entrypoint to `to_asyncio`
The function is useful if you want to run the "main process" under `asyncio`. Until `trio` core wraps this better we'll keep our own copy in the interim (there's a new "inside-out-guest" mode almost on mainline so hang tight).pre_bad_close
							parent
							
								
									1ba8a82dc6
								
							
						
					
					
						commit
						1172cffd46
					
				|  | @ -8,6 +8,7 @@ import trio  # type: ignore | ||||||
| 
 | 
 | ||||||
| from .log import get_console_log, get_logger | from .log import get_console_log, get_logger | ||||||
| from . import _state | from . import _state | ||||||
|  | from .to_asyncio import run_as_asyncio_guest | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| log = get_logger(__name__) | log = get_logger(__name__) | ||||||
|  | @ -44,7 +45,11 @@ def _mp_main( | ||||||
|         parent_addr=parent_addr |         parent_addr=parent_addr | ||||||
|     ) |     ) | ||||||
|     try: |     try: | ||||||
|         trio.run(trio_main) |         if infect_asyncio: | ||||||
|  |             actor._infected_aio = True | ||||||
|  |             run_as_asyncio_guest(trio_main) | ||||||
|  |         else: | ||||||
|  |             trio.run(trio_main) | ||||||
|     except KeyboardInterrupt: |     except KeyboardInterrupt: | ||||||
|         pass  # handle it the same way trio does? |         pass  # handle it the same way trio does? | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -13,10 +13,13 @@ from typing import ( | ||||||
| 
 | 
 | ||||||
| import trio | import trio | ||||||
| 
 | 
 | ||||||
|  | from .log import get_logger | ||||||
| from ._state import current_actor | from ._state import current_actor | ||||||
| 
 | 
 | ||||||
|  | log = get_logger(__name__) | ||||||
| 
 | 
 | ||||||
| __all__ = ['run'] | 
 | ||||||
|  | __all__ = ['run_task'] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| async def _invoke( | async def _invoke( | ||||||
|  | @ -40,7 +43,7 @@ async def _invoke( | ||||||
|         return await coro |         return await coro | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| async def run( | async def run_task( | ||||||
|     func: Callable, |     func: Callable, | ||||||
|     qsize: int = 2**10, |     qsize: int = 2**10, | ||||||
|     **kwargs, |     **kwargs, | ||||||
|  | @ -97,3 +100,51 @@ async def run( | ||||||
|                 raise err |                 raise err | ||||||
| 
 | 
 | ||||||
|     return result() |     return result() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def run_as_asyncio_guest( | ||||||
|  |     trio_main: Awaitable, | ||||||
|  | ) -> None: | ||||||
|  |     """Entry for an "infected ``asyncio`` actor". | ||||||
|  | 
 | ||||||
|  |     Uh, oh. :o | ||||||
|  | 
 | ||||||
|  |     It looks like your event loop has caught a case of the ``trio``s. | ||||||
|  | 
 | ||||||
|  |     :() | ||||||
|  | 
 | ||||||
|  |     Don't worry, we've heard you'll barely notice. You might hallucinate | ||||||
|  |     a few more propagating errors and feel like your digestion has | ||||||
|  |     slowed but if anything get's too bad your parents will know about | ||||||
|  |     it. | ||||||
|  | 
 | ||||||
|  |     :) | ||||||
|  |     """ | ||||||
|  |     async def aio_main(trio_main): | ||||||
|  |         loop = asyncio.get_running_loop() | ||||||
|  | 
 | ||||||
|  |         trio_done_fut = asyncio.Future() | ||||||
|  | 
 | ||||||
|  |         def trio_done_callback(main_outcome): | ||||||
|  |             log.info(f"trio_main finished: {main_outcome!r}") | ||||||
|  |             trio_done_fut.set_result(main_outcome) | ||||||
|  | 
 | ||||||
|  |         # start the infection: run trio on the asyncio loop in "guest mode" | ||||||
|  |         log.info(f"Infecting asyncio process with {trio_main}") | ||||||
|  |         trio.lowlevel.start_guest_run( | ||||||
|  |             trio_main, | ||||||
|  |             run_sync_soon_threadsafe=loop.call_soon_threadsafe, | ||||||
|  |             done_callback=trio_done_callback, | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         (await trio_done_fut).unwrap() | ||||||
|  | 
 | ||||||
|  |     # might as well if it's installed. | ||||||
|  |     try: | ||||||
|  |         import uvloop | ||||||
|  |         loop = uvloop.new_event_loop() | ||||||
|  |         asyncio.set_event_loop(loop) | ||||||
|  |     except ImportError: | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     asyncio.run(aio_main(trio_main)) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue