forked from goodboy/tractor
				
			Factor OCA supervisor into new func
							parent
							
								
									35775c6763
								
							
						
					
					
						commit
						b285db4c58
					
				| 
						 | 
				
			
			@ -164,7 +164,10 @@ async def open_root_actor(
 | 
			
		|||
            )
 | 
			
		||||
            try:
 | 
			
		||||
                yield actor
 | 
			
		||||
                # result = await main()
 | 
			
		||||
 | 
			
		||||
            # except BaseException as err:
 | 
			
		||||
            #     breakpoint()
 | 
			
		||||
 | 
			
		||||
            except (Exception, trio.MultiError) as err:
 | 
			
		||||
                logger.exception("Actor crashed:")
 | 
			
		||||
                await _debug._maybe_enter_pm(err)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -201,38 +201,9 @@ class ActorNursery:
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
@asynccontextmanager
 | 
			
		||||
async def open_nursery(
 | 
			
		||||
    **kwargs,
 | 
			
		||||
async def _open_and_supervise_one_cancels_all_nursery(
 | 
			
		||||
    actor: Actor,
 | 
			
		||||
) -> typing.AsyncGenerator[ActorNursery, None]:
 | 
			
		||||
    """Create and yield a new ``ActorNursery`` to be used for spawning
 | 
			
		||||
    structured concurrent subactors.
 | 
			
		||||
 | 
			
		||||
    When an actor is spawned a new trio task is started which
 | 
			
		||||
    invokes one of the process spawning backends to create and start
 | 
			
		||||
    a new subprocess. These tasks are started by one of two nurseries
 | 
			
		||||
    detailed below. The reason for spawning processes from within
 | 
			
		||||
    a new task is because ``trio_run_in_process`` itself creates a new
 | 
			
		||||
    internal nursery and the same task that opens a nursery **must**
 | 
			
		||||
    close it. It turns out this approach is probably more correct
 | 
			
		||||
    anyway since it is more clear from the following nested nurseries
 | 
			
		||||
    which cancellation scopes correspond to each spawned subactor set.
 | 
			
		||||
    """
 | 
			
		||||
    implicit_runtime = False
 | 
			
		||||
 | 
			
		||||
    actor = current_actor(err_on_no_runtime=False)
 | 
			
		||||
 | 
			
		||||
    if actor is None and is_main_process():
 | 
			
		||||
 | 
			
		||||
        # if we are the parent process start the actor runtime implicitly
 | 
			
		||||
        log.info("Starting actor runtime!")
 | 
			
		||||
        root_runtime_stack = AsyncExitStack()
 | 
			
		||||
        actor = await root_runtime_stack.enter_async_context(
 | 
			
		||||
            open_root_actor(**kwargs)
 | 
			
		||||
        )
 | 
			
		||||
        assert actor is current_actor()
 | 
			
		||||
 | 
			
		||||
        # mark us for teardown on exit
 | 
			
		||||
        implicit_runtime = True
 | 
			
		||||
 | 
			
		||||
    # the collection of errors retreived from spawned sub-actors
 | 
			
		||||
    errors: Dict[Tuple[str, str], Exception] = {}
 | 
			
		||||
| 
						 | 
				
			
			@ -243,7 +214,8 @@ async def open_nursery(
 | 
			
		|||
    # a supervisor strategy **before** blocking indefinitely to wait for
 | 
			
		||||
    # actors spawned in "daemon mode" (aka started using
 | 
			
		||||
    # ``ActorNursery.start_actor()``).
 | 
			
		||||
    try:
 | 
			
		||||
 | 
			
		||||
    # errors from this daemon actor nursery bubble up to caller
 | 
			
		||||
    async with trio.open_nursery() as da_nursery:
 | 
			
		||||
        try:
 | 
			
		||||
            # This is the inner level "run in actor" nursery. It is
 | 
			
		||||
| 
						 | 
				
			
			@ -348,6 +320,49 @@ async def open_nursery(
 | 
			
		|||
        # ria_nursery scope end - nursery checkpoint
 | 
			
		||||
 | 
			
		||||
    # after nursery exit
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@asynccontextmanager
 | 
			
		||||
async def open_nursery(
 | 
			
		||||
    **kwargs,
 | 
			
		||||
) -> typing.AsyncGenerator[ActorNursery, None]:
 | 
			
		||||
    """Create and yield a new ``ActorNursery`` to be used for spawning
 | 
			
		||||
    structured concurrent subactors.
 | 
			
		||||
 | 
			
		||||
    When an actor is spawned a new trio task is started which
 | 
			
		||||
    invokes one of the process spawning backends to create and start
 | 
			
		||||
    a new subprocess. These tasks are started by one of two nurseries
 | 
			
		||||
    detailed below. The reason for spawning processes from within
 | 
			
		||||
    a new task is because ``trio_run_in_process`` itself creates a new
 | 
			
		||||
    internal nursery and the same task that opens a nursery **must**
 | 
			
		||||
    close it. It turns out this approach is probably more correct
 | 
			
		||||
    anyway since it is more clear from the following nested nurseries
 | 
			
		||||
    which cancellation scopes correspond to each spawned subactor set.
 | 
			
		||||
    """
 | 
			
		||||
    implicit_runtime = False
 | 
			
		||||
 | 
			
		||||
    actor = current_actor(err_on_no_runtime=False)
 | 
			
		||||
 | 
			
		||||
    if actor is None and is_main_process():
 | 
			
		||||
 | 
			
		||||
        # if we are the parent process start the actor runtime implicitly
 | 
			
		||||
        log.info("Starting actor runtime!")
 | 
			
		||||
        root_runtime_stack = AsyncExitStack()
 | 
			
		||||
        actor = await root_runtime_stack.enter_async_context(
 | 
			
		||||
            open_root_actor(**kwargs)
 | 
			
		||||
        )
 | 
			
		||||
        assert actor is current_actor()
 | 
			
		||||
 | 
			
		||||
        # mark us for teardown on exit
 | 
			
		||||
        implicit_runtime = True
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        async with _open_and_supervise_one_cancels_all_nursery(
 | 
			
		||||
            actor
 | 
			
		||||
        ) as anursery:
 | 
			
		||||
 | 
			
		||||
            yield anursery
 | 
			
		||||
 | 
			
		||||
    finally:
 | 
			
		||||
        log.debug("Nursery teardown complete")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue