예제 #1
0
    def _from_class(cls, base_class: type) -> "VirtualActorClass":
        """Construct the virtual actor class from a base class."""
        # TODO(suquark): we may use more complex name for private functions
        # to avoid collision with user-defined functions.
        for attribute in [
            "create",
            "_create",
            "option",
            "_construct",
            "_from_class",
        ]:
            if hasattr(base_class, attribute):
                logger.warning(
                    "Creating an actor from class "
                    f"{base_class.__name__} overwrites "
                    f"attribute {attribute} of that class"
                )

        if not is_function_or_method(getattr(base_class, "__init__", None)):
            # Add __init__ if it does not exist.
            # Actor creation will be executed with __init__ together.

            # Assign an __init__ function will avoid many checks later on.
            def __init__(self):
                pass

            base_class.__init__ = __init__

        # Make sure the actor class we are constructing inherits from the
        # original class so it retains all class properties.
        class DerivedActorClass(cls, base_class):
            pass

        metadata = VirtualActorMetadata(base_class)
        has_getstate = "__getstate__" in metadata.methods
        has_setstate = "__setstate__" in metadata.methods

        if not has_getstate and not has_setstate:
            # This is OK since we'll use default one defined
            pass
        elif not has_getstate:
            raise ValueError("The class does not have '__getstate__' method")
        elif not has_setstate:
            raise ValueError("The class does not have '__setstate__' method")

        DerivedActorClass.__module__ = metadata.module
        name = f"VirtualActorClass({metadata.name})"
        DerivedActorClass.__name__ = name
        DerivedActorClass.__qualname__ = name
        # Construct the base object.

        self = DerivedActorClass.__new__(DerivedActorClass)

        self._metadata = metadata
        return self
예제 #2
0
def modify_class(cls):
    # cls has been modified.
    if hasattr(cls, "__ray_actor_class__"):
        return cls

    # Give an error if cls is an old-style class.
    if not issubclass(cls, object):
        raise TypeError(
            "The @ray.remote decorator cannot be applied to old-style "
            "classes. In Python 2, you must declare the class with "
            "'class ClassName(object):' instead of 'class ClassName:'.")

    # Modify the class to have an additional method that will be used for
    # terminating the worker.
    class Class(cls):
        __ray_actor_class__ = cls  # The original actor class

        def __ray_terminate__(self):
            worker = ray.worker.global_worker
            if worker.mode != ray.LOCAL_MODE:
                ray.actor.exit_actor()

    Class.__module__ = cls.__module__
    Class.__name__ = cls.__name__

    if not is_function_or_method(getattr(Class, "__init__", None)):
        # Add __init__ if it does not exist.
        # Actor creation will be executed with __init__ together.

        # Assign an __init__ function will avoid many checks later on.
        def __init__(self):
            pass

        Class.__init__ = __init__

    return Class