commit
						2674c54c0b
					
				|  | @ -0,0 +1,31 @@ | |||
| import tractor | ||||
| import trio | ||||
| 
 | ||||
| 
 | ||||
| async def breakpoint_forever(): | ||||
|     "Indefinitely re-enter debugger in child actor." | ||||
|     while True: | ||||
|         yield 'yo' | ||||
|         await tractor.breakpoint() | ||||
| 
 | ||||
| 
 | ||||
| async def name_error(): | ||||
|     "Raise a ``NameError``" | ||||
|     getattr(doggypants) | ||||
| 
 | ||||
| 
 | ||||
| async def main(): | ||||
|     """Test breakpoint in a streaming actor. | ||||
|     """ | ||||
|     async with tractor.open_nursery() as n: | ||||
| 
 | ||||
|         p0 = await n.start_actor('bp_forever', rpc_module_paths=[__name__]) | ||||
|         p1 = await n.start_actor('name_error', rpc_module_paths=[__name__]) | ||||
| 
 | ||||
|         # retreive results | ||||
|         stream = await p0.run(__name__, 'breakpoint_forever') | ||||
|         await p1.run(__name__, 'name_error') | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     tractor.run(main, debug_mode=True, loglevel='error') | ||||
|  | @ -282,6 +282,34 @@ def test_multi_subactors(spawn): | |||
|     assert 'bdb.BdbQuit' in before | ||||
| 
 | ||||
| 
 | ||||
| def test_multi_daemon_subactors(spawn): | ||||
|     """Multiple daemon subactors, both erroring and breakpointing within a | ||||
|     stream. | ||||
|     """ | ||||
|     child = spawn('multi_daemon_subactors') | ||||
| 
 | ||||
|     child.expect(r"\(Pdb\+\+\)") | ||||
| 
 | ||||
|     before = str(child.before.decode()) | ||||
|     assert "Attaching pdb to actor: ('bp_forever'" in before | ||||
| 
 | ||||
|     child.sendline('c') | ||||
| 
 | ||||
|     # first name_error failure | ||||
|     child.expect(r"\(Pdb\+\+\)") | ||||
|     before = str(child.before.decode()) | ||||
|     assert "NameError" in before | ||||
| 
 | ||||
|     child.sendline('c') | ||||
| 
 | ||||
|     child.expect(r"\(Pdb\+\+\)") | ||||
|     before = str(child.before.decode()) | ||||
|     assert "tractor._exceptions.RemoteActorError: ('name_error'" in before | ||||
| 
 | ||||
|     child.sendline('c') | ||||
|     child.expect(pexpect.EOF) | ||||
| 
 | ||||
| 
 | ||||
| def test_multi_subactors_root_errors(spawn): | ||||
|     """Multiple subactors, both erroring and breakpointing as well as | ||||
|     a nested subactor erroring. | ||||
|  |  | |||
|  | @ -20,8 +20,8 @@ from ._state import current_actor | |||
| from . import _state | ||||
| from ._exceptions import RemoteActorError, ModuleNotExposed | ||||
| from ._debug import breakpoint, post_mortem | ||||
| from . import msg | ||||
| from . import _spawn | ||||
| from . import msg | ||||
| 
 | ||||
| 
 | ||||
| __all__ = [ | ||||
|  | @ -60,16 +60,23 @@ async def _main( | |||
|     """ | ||||
|     logger = log.get_logger('tractor') | ||||
| 
 | ||||
|     # mark top most level process as root actor | ||||
|     _state._runtime_vars['_is_root'] = True | ||||
| 
 | ||||
|     if start_method is not None: | ||||
|         _spawn.try_set_start_method(start_method) | ||||
| 
 | ||||
|     if debug_mode and _spawn._spawn_method == 'trio': | ||||
|         _state._runtime_vars['_debug_mode'] = True | ||||
| 
 | ||||
|         # expose internal debug module to every actor allowing | ||||
|         # for use of ``await tractor.breakpoint()`` | ||||
|         kwargs.setdefault('rpc_module_paths', []).append('tractor._debug') | ||||
| 
 | ||||
|     elif debug_mode: | ||||
|         raise RuntimeError("Debug mode is only supported for the `trio` backend!") | ||||
|         raise RuntimeError( | ||||
|             "Debug mode is only supported for the `trio` backend!" | ||||
|         ) | ||||
| 
 | ||||
|     main = partial(async_fn, *args) | ||||
| 
 | ||||
|  | @ -134,9 +141,6 @@ def run( | |||
| 
 | ||||
|     This is tractor's main entry and the start point for any async actor. | ||||
|     """ | ||||
|     # mark top most level process as root actor | ||||
|     _state._runtime_vars['_is_root'] = True | ||||
| 
 | ||||
|     return trio.run( | ||||
|         partial( | ||||
|             # our entry | ||||
|  |  | |||
|  | @ -301,7 +301,18 @@ class Actor: | |||
|         try: | ||||
|             return getattr(self._mods[ns], funcname) | ||||
|         except KeyError as err: | ||||
|             raise ModuleNotExposed(*err.args) | ||||
|             mne = ModuleNotExposed(*err.args) | ||||
| 
 | ||||
|             if ns == '__main__': | ||||
|                 msg = ( | ||||
|                     "\n\nMake sure you exposed the current module using:\n\n" | ||||
|                     "ActorNursery.start_actor(<name>, rpc_module_paths=" | ||||
|                     "[__name__])" | ||||
|                 ) | ||||
| 
 | ||||
|                 mne.msg += msg | ||||
| 
 | ||||
|             raise mne | ||||
| 
 | ||||
|     async def _stream_handler( | ||||
|         self, | ||||
|  | @ -591,7 +602,7 @@ class Actor: | |||
|                 # Receive runtime state from our parent | ||||
|                 parent_data = await chan.recv() | ||||
|                 log.debug( | ||||
|                     "Recieved state from parent:\n" | ||||
|                     "Received state from parent:\n" | ||||
|                     f"{parent_data}" | ||||
|                 ) | ||||
|                 accept_addr = ( | ||||
|  | @ -599,6 +610,7 @@ class Actor: | |||
|                     parent_data.pop('bind_port'), | ||||
|                 ) | ||||
|                 rvs = parent_data.pop('_runtime_vars') | ||||
|                 log.debug(f"Runtime vars are: {rvs}") | ||||
|                 rvs['_is_root'] = False | ||||
|                 _state._runtime_vars.update(rvs) | ||||
| 
 | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ async def get_root( | |||
| **kwargs, | ||||
| ) -> typing.AsyncGenerator[Union[Portal, LocalPortal], None]: | ||||
|     host, port = _runtime_vars['_root_mailbox'] | ||||
|     assert host is not None | ||||
|     async with _connect_chan(host, port) as chan: | ||||
|         async with open_portal(chan, **kwargs) as portal: | ||||
|             yield portal | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue