forked from goodboy/tractor
				
			Factor out msg unwrapping into a func
							parent
							
								
									0e7234aa68
								
							
						
					
					
						commit
						f6de7e0afd
					
				|  | @ -21,7 +21,7 @@ from .log import get_logger | ||||||
| from ._exceptions import ( | from ._exceptions import ( | ||||||
|     unpack_error, |     unpack_error, | ||||||
|     NoResult, |     NoResult, | ||||||
|     RemoteActorError, |     # RemoteActorError, | ||||||
|     ContextCancelled, |     ContextCancelled, | ||||||
| ) | ) | ||||||
| from ._streaming import Context, ReceiveMsgStream | from ._streaming import Context, ReceiveMsgStream | ||||||
|  | @ -54,8 +54,23 @@ def func_deats(func: Callable) -> Tuple[str, str]: | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | def _unwrap_msg( | ||||||
|  | 
 | ||||||
|  |     msg: dict[str, Any], | ||||||
|  |     channel: Channel | ||||||
|  | 
 | ||||||
|  | ) -> Any: | ||||||
|  |     try: | ||||||
|  |         return msg['return'] | ||||||
|  |     except KeyError: | ||||||
|  |         # internal error should never get here | ||||||
|  |         assert msg.get('cid'), "Received internal error at portal?" | ||||||
|  |         raise unpack_error(msg, channel) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class Portal: | class Portal: | ||||||
|     """A 'portal' to a(n) (remote) ``Actor``. |     ''' | ||||||
|  |     A 'portal' to a(n) (remote) ``Actor``. | ||||||
| 
 | 
 | ||||||
|     A portal is "opened" (and eventually closed) by one side of an |     A portal is "opened" (and eventually closed) by one side of an | ||||||
|     inter-actor communication context. The side which opens the portal |     inter-actor communication context. The side which opens the portal | ||||||
|  | @ -71,7 +86,7 @@ class Portal: | ||||||
|     function calling semantics are supported transparently; hence it is |     function calling semantics are supported transparently; hence it is | ||||||
|     like having a "portal" between the seperate actor memory spaces. |     like having a "portal" between the seperate actor memory spaces. | ||||||
| 
 | 
 | ||||||
|     """ |     ''' | ||||||
|     def __init__(self, channel: Channel) -> None: |     def __init__(self, channel: Channel) -> None: | ||||||
|         self.channel = channel |         self.channel = channel | ||||||
|         # when this is set to a tuple returned from ``_submit()`` then |         # when this is set to a tuple returned from ``_submit()`` then | ||||||
|  | @ -130,16 +145,11 @@ class Portal: | ||||||
|         resptype: str, |         resptype: str, | ||||||
|         first_msg: dict |         first_msg: dict | ||||||
| 
 | 
 | ||||||
|     ) -> tuple[Any, dict[str, Any]]: |     ) -> dict[str, Any]: | ||||||
|         assert resptype == 'asyncfunc'  # single response |  | ||||||
| 
 | 
 | ||||||
|  |         assert resptype == 'asyncfunc'  # single response | ||||||
|         msg = await recv_chan.receive() |         msg = await recv_chan.receive() | ||||||
|         try: |         return msg | ||||||
|             return msg['return'], msg |  | ||||||
|         except KeyError: |  | ||||||
|             # internal error should never get here |  | ||||||
|             assert msg.get('cid'), "Received internal error at portal?" |  | ||||||
|             raise unpack_error(msg, self.channel) |  | ||||||
| 
 | 
 | ||||||
|     async def result(self) -> Any: |     async def result(self) -> Any: | ||||||
|         """Return the result(s) from the remote actor's "main" task. |         """Return the result(s) from the remote actor's "main" task. | ||||||
|  | @ -162,19 +172,9 @@ class Portal: | ||||||
|         assert self._expect_result |         assert self._expect_result | ||||||
| 
 | 
 | ||||||
|         if self._result_msg is None: |         if self._result_msg is None: | ||||||
|             try: |             self._result_msg = await self._return_once(*self._expect_result) | ||||||
|                 result, self._result_msg = await self._return_once( |  | ||||||
|                     *self._expect_result) |  | ||||||
|             except RemoteActorError as err: |  | ||||||
|                 result = err |  | ||||||
|         else: |  | ||||||
|             result = self._result_msg['return'] |  | ||||||
| 
 | 
 | ||||||
|         # re-raise error on every call |         return _unwrap_msg(self._result_msg, self.channel) | ||||||
|         if isinstance(result, RemoteActorError): |  | ||||||
|             raise result |  | ||||||
| 
 |  | ||||||
|         return result |  | ||||||
| 
 | 
 | ||||||
|     async def _cancel_streams(self): |     async def _cancel_streams(self): | ||||||
|         # terminate all locally running async generator |         # terminate all locally running async generator | ||||||
|  | @ -249,10 +249,10 @@ class Portal: | ||||||
|             instance methods in the remote runtime. Currently this should only |             instance methods in the remote runtime. Currently this should only | ||||||
|             be used for `tractor` internals. |             be used for `tractor` internals. | ||||||
|         """ |         """ | ||||||
|         value, _ = await self._return_once( |         msg = await self._return_once( | ||||||
|             *(await self._submit(namespace_path, function_name, kwargs)) |             *(await self._submit(namespace_path, function_name, kwargs)) | ||||||
|         ) |         ) | ||||||
|         return value |         return _unwrap_msg(msg, self.channel) | ||||||
| 
 | 
 | ||||||
|     async def run( |     async def run( | ||||||
|         self, |         self, | ||||||
|  | @ -293,9 +293,12 @@ class Portal: | ||||||
| 
 | 
 | ||||||
|             fn_mod_path, fn_name = func_deats(func) |             fn_mod_path, fn_name = func_deats(func) | ||||||
| 
 | 
 | ||||||
|         return (await self._return_once( |         return _unwrap_msg( | ||||||
|             *(await self._submit(fn_mod_path, fn_name, kwargs)) |             await self._return_once( | ||||||
|         ))[0] |                 *(await self._submit(fn_mod_path, fn_name, kwargs)), | ||||||
|  |             ), | ||||||
|  |             self.channel, | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|     @asynccontextmanager |     @asynccontextmanager | ||||||
|     async def open_stream_from( |     async def open_stream_from( | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue