Repository: All-Hands-AI/OpenHands
File: third_party/runtime/impl/modal/modal_runtime.py (Python)

Code before:
            self.runtime_container_image_id,
            self.config.sandbox.runtime_extra_deps,
        )

        if self.attach_to_existing:
            if self.sid in MODAL_RUNTIME_IDS:
                sandbox_id = MODAL_RUNTIME_IDS[self.sid]
                self.log("debug", f"Attaching to existing Modal sandbox: {sandbox_id}")
                self.sandbox = modal.Sandbox.from_id(
                    sandbox_id, client=self.modal_client
                )
        else:
            self.set_runtime_status(RuntimeStatus.STARTING_RUNTIME)
            await call_sync_from_async(
                self._init_sandbox,
                sandbox_workspace_dir=self.config.workspace_mount_path_in_sandbox,
                plugins=self.plugins,
            )

            self.set_runtime_status(RuntimeStatus.RUNTIME_STARTED)

        if self.sandbox is None:
            raise Exception("Sandbox not initialized")
        tunnel = self.sandbox.tunnels()[self.container_port]
        self.api_url = tunnel.url
        print("Waiting 20 secs for the container to be ready... (avoiding RemoteProtocolError)")
        sleep(20)
        self.log("debug", f"Container started. Server url: {self.api_url}")

        if not self.attach_to_existing:
            self.log("debug", "Waiting for client to become ready...")
            self.set_runtime_status(RuntimeStatus.STARTING_RUNTIME)

        self._wait_until_alive()
        self.setup_initial_env()

        if not self.attach_to_existing:
            self.set_runtime_status(RuntimeStatus.READY)
        self._runtime_initialized = True

    @property
    def action_execution_server_url(self):
        return self.api_url

    @tenacity.retry(
        stop=tenacity.stop_after_delay(120) | stop_if_should_exit(),
        retry=tenacity.retry_if_exception_type((ConnectionError, httpx.NetworkError)),
        reraise=True,
        wait=tenacity.wait_fixed(2),
    )
    def _wait_until_alive(self):

Review comment (suggestion):
```suggestion
       self.log("info", "Waiting 20 secs for the container to be ready... (avoiding RemoteProtocolError)")
```

Code after:
            self.runtime_container_image_id,
            self.config.sandbox.runtime_extra_deps,
        )

        if self.attach_to_existing:
            if self.sid in MODAL_RUNTIME_IDS:
                sandbox_id = MODAL_RUNTIME_IDS[self.sid]
                self.log("debug", f"Attaching to existing Modal sandbox: {sandbox_id}")
                self.sandbox = modal.Sandbox.from_id(
                    sandbox_id, client=self.modal_client
                )
        else:
            self.set_runtime_status(RuntimeStatus.STARTING_RUNTIME)
            await call_sync_from_async(
                self._init_sandbox,
                sandbox_workspace_dir=self.config.workspace_mount_path_in_sandbox,
                plugins=self.plugins,
            )

            self.set_runtime_status(RuntimeStatus.RUNTIME_STARTED)

        if self.sandbox is None:
            raise Exception("Sandbox not initialized")
        tunnel = self.sandbox.tunnels()[self.container_port]
        self.api_url = tunnel.url
        self.log("info", "Waiting 20 secs for the container to be ready... (avoiding RemoteProtocolError)")
        sleep(20)
        self.log("debug", f"Container started. Server url: {self.api_url}")

        if not self.attach_to_existing:
            self.log("debug", "Waiting for client to become ready...")
            self.set_runtime_status(RuntimeStatus.STARTING_RUNTIME)

        self._wait_until_alive()
        self.setup_initial_env()

        if not self.attach_to_existing:
            self.set_runtime_status(RuntimeStatus.READY)
        self._runtime_initialized = True

    @property
    def action_execution_server_url(self):
        return self.api_url

    @tenacity.retry(
        stop=tenacity.stop_after_delay(120) | stop_if_should_exit(),
        retry=tenacity.retry_if_exception_type((ConnectionError, httpx.NetworkError)),
        reraise=True,
        wait=tenacity.wait_fixed(2),
    )
    def _wait_until_alive(self):