Repository: ray-project/ray
File: python/ray/serve/_private/controller.py (Python)

Code before:
        http_config = self.get_http_config()
        if http_config.root_url == "":
            # HTTP is disabled
            if http_config.host is None:
                return ""
            return (
                f"http://{build_address(http_config.host, http_config.port)}"
                f"{http_config.root_path}"
            )
        return http_config.root_url

    def config_checkpoint_deleted(self) -> bool:
        """Returns whether the config checkpoint has been deleted.

        Get the config checkpoint from the kv store. If it is None, then it has been
        deleted.
        """
        return self.kv_store.get(CONFIG_CHECKPOINT_KEY) is None

    def register_shutdown_cleanup_actor(self, actor_handle: ActorHandle) -> None:
        """Register an actor to be killed on serve.shutdown().

        This allows deployments to register auxiliary actors (like caches,
        coordinators, etc.) that should be cleaned up when Serve shuts down.
        The actors must use lifetime="detached" to survive replica restarts,
        but will be explicitly killed during serve.shutdown().

        Note: Registered actors are NOT persisted across controller restarts.
        For full persistence, use controller-managed deployment-scoped actors
        (see https://github.com/ray-project/ray/issues/60359).

        If the same actor is registered multiple times (e.g., from multiple
        router instances sharing a tree actor via get_if_exists=True), it will
        only be stored once.

        Args:
            actor_handle: The actor handle to register for cleanup.
        """
        actor_id = actor_handle._actor_id.hex()
        self._registered_cleanup_actors[actor_id] = actor_handle

    def _kill_registered_cleanup_actors(self) -> None:
        """Kill all actors registered for shutdown cleanup."""
        for actor in self._registered_cleanup_actors.values():
            try:
                ray.kill(actor, no_restart=True)
            except Exception:
                pass  # Actor may already be dead

    def shutdown(self):
        """Shuts down the serve instance completely.

Review comment (performance):
just curious: why do we need actors for these caches? is it possible to use deployment with `num_replicas=1` for them?

Code after:
        http_config = self.get_http_config()
        if http_config.root_url == "":
            # HTTP is disabled
            if http_config.host is None:
                return ""
            return (
                f"http://{build_address(http_config.host, http_config.port)}"
                f"{http_config.root_path}"
            )
        return http_config.root_url

    def config_checkpoint_deleted(self) -> bool:
        """Returns whether the config checkpoint has been deleted.

        Get the config checkpoint from the kv store. If it is None, then it has been
        deleted.
        """
        return self.kv_store.get(CONFIG_CHECKPOINT_KEY) is None

    def _register_shutdown_cleanup_actor(self, actor_handle: ActorHandle) -> None:
        """Register an actor to be killed on serve.shutdown().

        This allows deployments to register auxiliary actors (like caches,
        coordinators, etc.) that should be cleaned up when Serve shuts down.
        The actors must use lifetime="detached" to survive replica restarts,
        but will be explicitly killed during serve.shutdown().

        Note: Registered actors are NOT persisted across controller restarts.
        For full persistence, use controller-managed deployment-scoped actors
        (see https://github.com/ray-project/ray/issues/60359).

        If the same actor is registered multiple times (e.g., from multiple
        router instances sharing a tree actor via get_if_exists=True), it will
        only be stored once.

        Args:
            actor_handle: The actor handle to register for cleanup.
        """
        actor_id = actor_handle._actor_id.hex()
        self._registered_cleanup_actors[actor_id] = actor_handle

    def _kill_registered_cleanup_actors(self) -> None:
        """Kill all actors registered for shutdown cleanup."""
        for actor in self._registered_cleanup_actors.values():
            try:
                ray.kill(actor, no_restart=True)
            except Exception:
                pass  # Actor may already be dead

    def shutdown(self):
        """Shuts down the serve instance completely.