Example #1
0
    async def invoke_method(self,
                            actor_type: str,
                            actor_id: str,
                            method: str,
                            data: Optional[bytes] = None) -> bytes:
        """Invoke method defined in :class:`Actor` remotely.

        Args:
            actor_type (str): Actor type.
            actor_id (str): Id of Actor type.
            method (str): Method name defined in :class:`Actor`.
            bytes data (bytes): data which will be passed to the target actor.

        Returns:
            bytes: the response from the actor.
        """
        url = f'{self._get_base_url(actor_type, actor_id)}/method/{method}'

        # import to avoid circular dependency
        from dapr.actor.runtime.reentrancy_context import reentrancy_ctx
        reentrancy_id = reentrancy_ctx.get()
        headers: Dict[str,
                      Union[bytes,
                            str]] = ({
                                DAPR_REENTRANCY_ID_HEADER: reentrancy_id
                            } if reentrancy_id else {})

        body, _ = await self._client.send_bytes(method='POST',
                                                url=url,
                                                data=data,
                                                headers=headers)

        return body
Example #2
0
    async def _dispatch_internal(
        self, actor_id: ActorId, method_context: ActorMethodContext,
        dispatch_action: Callable[[Actor], Coroutine[Any, Any,
                                                     Optional[bytes]]]
    ) -> object:
        # Activate actor when actor is invoked.
        if actor_id.id not in self._active_actors:
            await self.activate_actor(actor_id)
        actor = None
        async with self._active_actors_lock:
            actor = self._active_actors.get(actor_id.id, None)
        if not actor:
            raise ValueError(f'{actor_id} is not activated')

        try:
            if reentrancy_ctx.get(None) is not None:
                actor._state_manager.set_state_context(str(uuid.uuid4()))
            await actor._on_pre_actor_method_internal(method_context)
            retval = await dispatch_action(actor)
            await actor._on_post_actor_method_internal(method_context)
        except DaprInternalError as ex:
            await actor._on_invoke_failed_internal(ex)
            raise ex
        finally:
            if reentrancy_ctx is not None:
                actor._state_manager.set_state_context(None)

        return retval
Example #3
0
 async def reentrant_method(self, data: object) -> str:
     return reentrancy_ctx.get()
Example #4
0
 async def reentrant_method(self, data: object) -> str:
     await asyncio.sleep(1)
     return reentrancy_ctx.get()
Example #5
0
 def _get_contextual_state_tracker(self) -> Dict[str, StateMetadata]:
     context = CONTEXT.get(None)
     if (context is not None and reentrancy_ctx.get(None) is not None):
         return context['tracker']
     else:
         return self._default_state_change_tracker