Create an actor. This method allows more flexibility than the remote method because resource requirements can be specified and override the defaults in the decorator. Args: args: The arguments to forward to the actor constructor. kwargs: The
(self, args=None, kwargs=None, **actor_options)
| 1753 | @wrap_auto_init |
| 1754 | @_tracing_actor_creation |
| 1755 | def _remote(self, args=None, kwargs=None, **actor_options) -> ActorProxy[T]: |
| 1756 | """Create an actor. |
| 1757 | |
| 1758 | This method allows more flexibility than the remote method because |
| 1759 | resource requirements can be specified and override the defaults in the |
| 1760 | decorator. |
| 1761 | |
| 1762 | Args: |
| 1763 | args: The arguments to forward to the actor constructor. |
| 1764 | kwargs: The keyword arguments to forward to the actor constructor. |
| 1765 | **actor_options: Keyword arguments for configuring the actor options. |
| 1766 | See ``ActorClass.options`` for more details. |
| 1767 | |
| 1768 | Returns: |
| 1769 | A handle to the newly created actor. |
| 1770 | """ |
| 1771 | name = actor_options.get("name") |
| 1772 | namespace = actor_options.get("namespace") |
| 1773 | if name is not None: |
| 1774 | if not isinstance(name, str): |
| 1775 | raise TypeError(f"name must be None or a string, got: '{type(name)}'.") |
| 1776 | elif name == "": |
| 1777 | raise ValueError("Actor name cannot be an empty string.") |
| 1778 | if namespace is not None: |
| 1779 | ray._private.utils.validate_namespace(namespace) |
| 1780 | |
| 1781 | # Handle the get-or-create case. |
| 1782 | if actor_options.get("get_if_exists"): |
| 1783 | try: |
| 1784 | return ray.get_actor(name, namespace=namespace) |
| 1785 | except ValueError: |
| 1786 | # Attempt to create it (may race with other attempts). |
| 1787 | updated_options = actor_options.copy() |
| 1788 | updated_options["get_if_exists"] = False # prevent infinite loop |
| 1789 | try: |
| 1790 | return self._remote(args, kwargs, **updated_options) |
| 1791 | except ActorAlreadyExistsError: |
| 1792 | pass |
| 1793 | # The actor was created between the first and second get_actor calls. |
| 1794 | # Try to get it again to see if it's there. |
| 1795 | return ray.get_actor(name, namespace=namespace) |
| 1796 | |
| 1797 | # We pop the "concurrency_groups" coming from "@ray.remote" here. We no longer |
| 1798 | # need it in "_remote()". |
| 1799 | actor_options.pop("concurrency_groups", None) |
| 1800 | |
| 1801 | if args is None: |
| 1802 | args = [] |
| 1803 | if kwargs is None: |
| 1804 | kwargs = {} |
| 1805 | meta = self.__ray_metadata__ |
| 1806 | is_asyncio = has_async_methods(meta.modified_class) |
| 1807 | |
| 1808 | if actor_options.get("max_concurrency") is None: |
| 1809 | actor_options["max_concurrency"] = ( |
| 1810 | DEFAULT_MAX_CONCURRENCY_ASYNC |
| 1811 | if is_asyncio |
| 1812 | else ray_constants.DEFAULT_MAX_CONCURRENCY_THREADED |
no test coverage detected