def test_controller_starts_java_replica(shutdown_only): # noqa: F811 ray.init( num_cpus=8, namespace="default_test_namespace", # A dummy code search path to enable cross language. job_config=JobConfig(code_search_path=["."]), ) client = serve.start(detached=True) controller = client._controller config = DeploymentConfig() config.deployment_language = JAVA config.is_cross_language = True replica_config = ReplicaConfig.create( "io.ray.serve.util.ExampleEchoDeployment", init_args=["my_prefix "], ) # Deploy it deployment_name = "my_java" updating = ray.get( controller.deploy.remote( name=deployment_name, deployment_config_proto_bytes=config.to_proto_bytes(), replica_config_proto_bytes=replica_config.to_proto_bytes(), route_prefix=None, deployer_job_id=ray.get_runtime_context().job_id, ) ) assert updating client._wait_for_deployment_healthy(deployment_name) # Let's try to call it! all_handles = ray.get(controller._all_running_replicas.remote()) backend_handle = all_handles["my_java"][0].actor_handle out = backend_handle.handleRequest.remote( RequestMetadata( request_id="id-1", endpoint="endpoint", call_method="call", ).SerializeToString(), RequestWrapper(body=msgpack_serialize("hello")).SerializeToString(), ) assert ray.get(out) == "my_prefix hello" handle = serve.get_deployment("my_java").get_handle() handle_out = handle.remote("hello handle") assert ray.get(handle_out) == "my_prefix hello handle" ray.get(controller.delete_deployment.remote(deployment_name)) client._wait_for_deployment_deleted(deployment_name)
def test_replica_config_validation(self): class Class: pass def function(_): pass ReplicaConfig.create(Class) ReplicaConfig.create(function) with pytest.raises(TypeError): ReplicaConfig.create(Class()) # Check ray_actor_options validation. ReplicaConfig.create( Class, tuple(), dict(), ray_actor_options={ "num_cpus": 1.0, "num_gpus": 10, "resources": {"abc": 1.0}, "memory": 1000000.0, "object_store_memory": 1000000, }, ) with pytest.raises(TypeError): ReplicaConfig.create(Class, ray_actor_options=1.0) with pytest.raises(TypeError): ReplicaConfig.create(Class, ray_actor_options=False) with pytest.raises(TypeError): ReplicaConfig.create(Class, ray_actor_options={"num_cpus": "hello"}) with pytest.raises(ValueError): ReplicaConfig.create(Class, ray_actor_options={"num_cpus": -1}) with pytest.raises(TypeError): ReplicaConfig.create(Class, ray_actor_options={"num_gpus": "hello"}) with pytest.raises(ValueError): ReplicaConfig.create(Class, ray_actor_options={"num_gpus": -1}) with pytest.raises(TypeError): ReplicaConfig.create(Class, ray_actor_options={"memory": "hello"}) with pytest.raises(ValueError): ReplicaConfig.create(Class, ray_actor_options={"memory": -1}) with pytest.raises(TypeError): ReplicaConfig.create( Class, ray_actor_options={"object_store_memory": "hello"} ) with pytest.raises(ValueError): ReplicaConfig.create(Class, ray_actor_options={"object_store_memory": -1}) with pytest.raises(TypeError): ReplicaConfig.create(Class, ray_actor_options={"resources": []}) disallowed_ray_actor_options = { "max_concurrency", "max_restarts", "max_task_retries", "name", "namespace", "lifetime", "placement_group", "placement_group_bundle_index", "placement_group_capture_child_tasks", "max_pending_calls", "scheduling_strategy", "get_if_exists", "_metadata", } for option in disallowed_ray_actor_options: with pytest.raises(ValueError): ReplicaConfig.create(Class, ray_actor_options={option: None})
def get_deploy_args( self, name: str, deployment_def: Union[Callable, Type[Callable], str], init_args: Tuple[Any], init_kwargs: Dict[Any, Any], ray_actor_options: Optional[Dict] = None, config: Optional[Union[DeploymentConfig, Dict[str, Any]]] = None, version: Optional[str] = None, route_prefix: Optional[str] = None, ) -> Dict: """ Takes a deployment's configuration, and returns the arguments needed for the controller to deploy it. """ if config is None: config = {} if ray_actor_options is None: ray_actor_options = {} curr_job_env = ray.get_runtime_context().runtime_env if "runtime_env" in ray_actor_options: # It is illegal to set field working_dir to None. if curr_job_env.get("working_dir") is not None: ray_actor_options["runtime_env"].setdefault( "working_dir", curr_job_env.get("working_dir")) else: ray_actor_options["runtime_env"] = curr_job_env replica_config = ReplicaConfig.create( deployment_def, init_args=init_args, init_kwargs=init_kwargs, ray_actor_options=ray_actor_options, ) if isinstance(config, dict): deployment_config = DeploymentConfig.parse_obj(config) elif isinstance(config, DeploymentConfig): deployment_config = config else: raise TypeError( "config must be a DeploymentConfig or a dictionary.") deployment_config.version = version if (deployment_config.autoscaling_config is not None and deployment_config.max_concurrent_queries < deployment_config.autoscaling_config. target_num_ongoing_requests_per_replica # noqa: E501 ): logger.warning("Autoscaling will never happen, " "because 'max_concurrent_queries' is less than " "'target_num_ongoing_requests_per_replica' now.") controller_deploy_args = { "name": name, "deployment_config_proto_bytes": deployment_config.to_proto_bytes(), "replica_config_proto_bytes": replica_config.to_proto_bytes(), "route_prefix": route_prefix, "deployer_job_id": ray.get_runtime_context().job_id, } return controller_deploy_args