Exemple #1
0
 async def get_all_deployment_statuses(self, req: Request) -> Response:
     serve_application_status_schema = serve_application_status_to_schema(
         get_deployment_statuses())
     return Response(
         text=serve_application_status_schema.json(),
         content_type="application/json",
     )
Exemple #2
0
    def run(self, logger: Union[Logger, _CliLogger] = logger):
        """Deploys all deployments in this Application and logs status.

        This function keeps looping and printing status, so it must be manually
        killed (e.g. using ctrl-C). When it recieves a kill signal, it tears
        down all deployments that it deployed. If there are no deployments
        left, it also shuts down the rest of Serve, including the controller.
        This is meant to help interactive development.

        Args:
            logger: Any Python object that implements the standard logger
                interface.
        """

        try:
            serve.start(detached=True)
            self.deploy()

            logger.info("\nDeployed successfully!\n")

            while True:
                statuses = serve_application_status_to_schema(
                    get_deployment_statuses()
                ).json(indent=4)
                logger.info(f"{statuses}")
                time.sleep(10)

        except KeyboardInterrupt:
            logger.info("Got SIGINT (KeyboardInterrupt). Removing deployments.")
            for deployment in self._deployments.values():
                deployment.delete()
            if len(serve.list_deployments()) == 0:
                logger.info("No deployments left. Shutting down Serve.")
                serve.shutdown()
            sys.exit()
Exemple #3
0
def run(
    config_or_import_path: str,
    runtime_env: str,
    runtime_env_json: str,
    working_dir: str,
    app_dir: str,
    address: str,
    host: str,
    port: int,
    blocking: bool,
):
    sys.path.insert(0, app_dir)

    final_runtime_env = parse_runtime_env_args(
        runtime_env=runtime_env,
        runtime_env_json=runtime_env_json,
        working_dir=working_dir,
    )

    app_or_node = None
    if pathlib.Path(config_or_import_path).is_file():
        config_path = config_or_import_path
        cli_logger.print(f"Loading app from config file: '{config_path}'.")
        with open(config_path, "r") as config_file:
            app_or_node = Application.from_yaml(config_file)
    else:
        import_path = config_or_import_path
        cli_logger.print(f"Loading app from import path: '{import_path}'.")
        app_or_node = import_attr(import_path)

    # Setting the runtime_env here will set defaults for the deployments.
    ray.init(address=address, namespace="serve", runtime_env=final_runtime_env)

    try:
        serve.run(app_or_node, host=host, port=port)
        cli_logger.success("Deployed successfully!\n")

        if blocking:
            while True:
                statuses = serve_application_status_to_schema(
                    get_deployment_statuses()
                ).json(indent=4)
                cli_logger.info(f"{statuses}")
                time.sleep(10)

    except KeyboardInterrupt:
        cli_logger.info("Got KeyboardInterrupt, shutting down...")
        serve.shutdown()
        sys.exit()
Exemple #4
0
def test_serve_application_to_schema_to_serve_application():
    @serve.deployment(
        num_replicas=1,
        route_prefix="/hello",
    )
    def f1():
        # The body of this function doesn't matter. See the comment in
        # test_deployment_to_schema_to_deployment.
        pass

    @serve.deployment(
        num_replicas=2,
        route_prefix="/hi",
    )
    def f2():
        pass

    f1._func_or_class = "ray.dashboard.modules.serve.tests.test_schema.global_f"
    f2._func_or_class = "ray.dashboard.modules.serve.tests.test_schema.global_f"

    deployments = schema_to_serve_application(
        serve_application_to_schema([f1, f2]))

    assert deployments[0].num_replicas == 1
    assert deployments[0].route_prefix == "/hello"
    assert deployments[1].num_replicas == 2
    assert deployments[1].route_prefix == "/hi"

    serve.start()

    deployments[0].deploy()
    deployments[1].deploy()
    assert ray.get(deployments[0].get_handle().remote()) == "Hello world!"
    assert requests.get("http://localhost:8000/hello").text == "Hello world!"
    assert ray.get(deployments[1].get_handle().remote()) == "Hello world!"
    assert requests.get("http://localhost:8000/hi").text == "Hello world!"

    # Check statuses
    statuses = serve_application_status_to_schema(
        get_deployment_statuses()).statuses
    deployment_names = {"f1", "f2"}
    for deployment_status in statuses:
        assert deployment_status.status in {"UPDATING", "HEALTHY"}
        assert deployment_status.name in deployment_names
        deployment_names.remove(deployment_status.name)
    assert len(deployment_names) == 0

    serve.shutdown()
Exemple #5
0
def test_status_schema_helpers():
    @serve.deployment(
        num_replicas=1,
        route_prefix="/hello",
    )
    def f1():
        # The body of this function doesn't matter. See the comment in
        # test_deployment_to_schema_to_deployment.
        pass

    @serve.deployment(
        num_replicas=2,
        route_prefix="/hi",
    )
    def f2():
        pass

    f1._func_or_class = "ray.serve.tests.test_schema.global_f"
    f2._func_or_class = "ray.serve.tests.test_schema.global_f"

    serve.start()

    f1.deploy()
    f2.deploy()

    # Check statuses
    statuses = serve_application_status_to_schema(
        get_deployment_statuses()).statuses
    deployment_names = {"f1", "f2"}
    for deployment_status in statuses:
        assert deployment_status.status in {"UPDATING", "HEALTHY"}
        assert deployment_status.name in deployment_names
        deployment_names.remove(deployment_status.name)
    assert len(deployment_names) == 0

    serve.shutdown()