forked from goodboy/tractor
				
			First draft "namespace path" named tuple; probably will discard
							parent
							
								
									094206ee9d
								
							
						
					
					
						commit
						949cb2c9fe
					
				| 
						 | 
					@ -14,11 +14,13 @@
 | 
				
			||||||
# You should have received a copy of the GNU Affero General Public License
 | 
					# You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"""
 | 
					'''
 | 
				
			||||||
Memory boundary "Portals": an API for structured
 | 
					Memory boundary "Portals": an API for structured
 | 
				
			||||||
concurrency linked tasks running in disparate memory domains.
 | 
					concurrency linked tasks running in disparate memory domains.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"""
 | 
					'''
 | 
				
			||||||
 | 
					from __future__ import annotations
 | 
				
			||||||
 | 
					from typing import NamedTuple
 | 
				
			||||||
import importlib
 | 
					import importlib
 | 
				
			||||||
import inspect
 | 
					import inspect
 | 
				
			||||||
from typing import (
 | 
					from typing import (
 | 
				
			||||||
| 
						 | 
					@ -66,12 +68,39 @@ async def maybe_open_nursery(
 | 
				
			||||||
            yield nursery
 | 
					            yield nursery
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def func_deats(func: Callable) -> tuple[str, str]:
 | 
					class NamespacePath(NamedTuple):
 | 
				
			||||||
    return (
 | 
					    '''
 | 
				
			||||||
        func.__module__,
 | 
					    A serializeable description of a (function) object location
 | 
				
			||||||
        func.__name__,
 | 
					    described by the target's module path and its namespace key.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    mod: str
 | 
				
			||||||
 | 
					    key: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def load(self) -> Callable:
 | 
				
			||||||
 | 
					        return getattr(
 | 
				
			||||||
 | 
					            importlib.import_module(self.mod),
 | 
				
			||||||
 | 
					            self.key
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def from_ref(
 | 
				
			||||||
 | 
					        cls,
 | 
				
			||||||
 | 
					        obj,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ) -> NamespacePath:
 | 
				
			||||||
 | 
					        return cls(
 | 
				
			||||||
 | 
					            obj.__module__,
 | 
				
			||||||
 | 
					            obj.__name__,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# def func_deats(func: Callable) -> NamespacePath[str, str]:
 | 
				
			||||||
 | 
					#     return NamespacePath(
 | 
				
			||||||
 | 
					#         func.__module__,
 | 
				
			||||||
 | 
					#         func.__name__,
 | 
				
			||||||
 | 
					#     )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _unwrap_msg(
 | 
					def _unwrap_msg(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,6 +115,7 @@ def _unwrap_msg(
 | 
				
			||||||
        assert msg.get('cid'), "Received internal error at portal?"
 | 
					        assert msg.get('cid'), "Received internal error at portal?"
 | 
				
			||||||
        raise unpack_error(msg, channel)
 | 
					        raise unpack_error(msg, channel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MessagingError(Exception):
 | 
					class MessagingError(Exception):
 | 
				
			||||||
    'Some kind of unexpected SC messaging dialog issue'
 | 
					    'Some kind of unexpected SC messaging dialog issue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -316,7 +346,8 @@ class Portal:
 | 
				
			||||||
                raise TypeError(
 | 
					                raise TypeError(
 | 
				
			||||||
                    f'{func} must be a non-streaming async function!')
 | 
					                    f'{func} must be a non-streaming async function!')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fn_mod_path, fn_name = func_deats(func)
 | 
					            # fn_mod_path, fn_name = func_deats(func)
 | 
				
			||||||
 | 
					            fn_mod_path, fn_name = NamespacePath.from_ref(func)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ctx = await self.actor.start_remote_task(
 | 
					        ctx = await self.actor.start_remote_task(
 | 
				
			||||||
            self.channel,
 | 
					            self.channel,
 | 
				
			||||||
| 
						 | 
					@ -346,7 +377,8 @@ class Portal:
 | 
				
			||||||
                raise TypeError(
 | 
					                raise TypeError(
 | 
				
			||||||
                    f'{async_gen_func} must be an async generator function!')
 | 
					                    f'{async_gen_func} must be an async generator function!')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fn_mod_path, fn_name = func_deats(async_gen_func)
 | 
					        # fn_mod_path, fn_name = func_deats(async_gen_func)
 | 
				
			||||||
 | 
					        fn_mod_path, fn_name = NamespacePath.from_ref(async_gen_func)
 | 
				
			||||||
        ctx = await self.actor.start_remote_task(
 | 
					        ctx = await self.actor.start_remote_task(
 | 
				
			||||||
            self.channel,
 | 
					            self.channel,
 | 
				
			||||||
            fn_mod_path,
 | 
					            fn_mod_path,
 | 
				
			||||||
| 
						 | 
					@ -412,7 +444,8 @@ class Portal:
 | 
				
			||||||
            raise TypeError(
 | 
					            raise TypeError(
 | 
				
			||||||
                f'{func} must be an async generator function!')
 | 
					                f'{func} must be an async generator function!')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fn_mod_path, fn_name = func_deats(func)
 | 
					        # fn_mod_path, fn_name = func_deats(func)
 | 
				
			||||||
 | 
					        fn_mod_path, fn_name = NamespacePath.from_ref(func)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ctx = await self.actor.start_remote_task(
 | 
					        ctx = await self.actor.start_remote_task(
 | 
				
			||||||
            self.channel,
 | 
					            self.channel,
 | 
				
			||||||
| 
						 | 
					@ -430,7 +463,7 @@ class Portal:
 | 
				
			||||||
            first = msg['started']
 | 
					            first = msg['started']
 | 
				
			||||||
            ctx._started_called = True
 | 
					            ctx._started_called = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        except KeyError as kerr:
 | 
					        except KeyError:
 | 
				
			||||||
            assert msg.get('cid'), ("Received internal error at context?")
 | 
					            assert msg.get('cid'), ("Received internal error at context?")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if msg.get('error'):
 | 
					            if msg.get('error'):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue