From a3f8f2817e89c13b1fbed844592d1c8c8d3b227a Mon Sep 17 00:00:00 2001 From: Shreyas Krishnaswamy Date: Wed, 16 Mar 2022 18:58:44 -0700 Subject: [PATCH 1/3] Implement set_options --- python/ray/serve/api.py | 69 ++++++++++++++++++++++++++++++ python/ray/serve/tests/test_api.py | 38 ++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/python/ray/serve/api.py b/python/ray/serve/api.py index b0cda6cc54b1..e5564ccf9286 100644 --- a/python/ray/serve/api.py +++ b/python/ray/serve/api.py @@ -1216,6 +1216,9 @@ def options( if version is None: version = self._version + if prev_version is None: + prev_version = self._prev_version + if init_args is None: init_args = self._init_args @@ -1257,6 +1260,72 @@ def options( _internal=True, ) + @PublicAPI + def set_options( + self, + func_or_class: Optional[Callable] = None, + name: Optional[str] = None, + version: Optional[str] = None, + prev_version: Optional[str] = None, + init_args: Optional[Tuple[Any]] = None, + init_kwargs: Optional[Dict[Any, Any]] = None, + route_prefix: Union[str, None, DEFAULT] = DEFAULT.VALUE, + num_replicas: Optional[int] = None, + ray_actor_options: Optional[Dict] = None, + user_config: Optional[Any] = None, + max_concurrent_queries: Optional[int] = None, + _autoscaling_config: Optional[Union[Dict, AutoscalingConfig]] = None, + _graceful_shutdown_wait_loop_s: Optional[float] = None, + _graceful_shutdown_timeout_s: Optional[float] = None, + _health_check_period_s: Optional[float] = None, + _health_check_timeout_s: Optional[float] = None, + ) -> None: + """Overwrite this deployment's options. Mutates the deployment. + + Only those options passed in will be updated, all others will remain + unchanged. + """ + + validated = self.options( + func_or_class=func_or_class, + name=name, + version=version, + prev_version=prev_version, + init_args=init_args, + init_kwargs=init_kwargs, + route_prefix=route_prefix, + num_replicas=num_replicas, + ray_actor_options=ray_actor_options, + user_config=user_config, + max_concurrent_queries=max_concurrent_queries, + _autoscaling_config=_autoscaling_config, + _graceful_shutdown_wait_loop_s=_graceful_shutdown_wait_loop_s, + _graceful_shutdown_timeout_s=_graceful_shutdown_timeout_s, + _health_check_period_s=_health_check_period_s, + _health_check_timeout_s=_health_check_timeout_s, + ) + + self._config.num_replicas = validated._config.num_replicas + self._config.user_config = validated._config.user_config + self._config.max_concurrent_queries = validated._config.max_concurrent_queries + self._func_or_class = validated._func_or_class + self._name = validated._name + self._version = validated._version + self._prev_version = validated._prev_version + self._init_args = validated._init_args + self._init_kwargs = validated._init_kwargs + self._route_prefix = validated._route_prefix + self._ray_actor_options = validated._ray_actor_options + self._config.autoscaling_config = validated._config.autoscaling_config + self._config.graceful_shutdown_wait_loop_s = ( + validated._config.graceful_shutdown_wait_loop_s + ) + self._config.graceful_shutdown_timeout_s = ( + validated._config.graceful_shutdown_timeout_s + ) + self._config.health_check_period_s = validated._config.health_check_period_s + self._config.health_check_timeout_s = validated._config.health_check_timeout_s + def __eq__(self, other): return all( [ diff --git a/python/ray/serve/tests/test_api.py b/python/ray/serve/tests/test_api.py index 1a3f846a3d41..8fae6b325a55 100644 --- a/python/ray/serve/tests/test_api.py +++ b/python/ray/serve/tests/test_api.py @@ -302,6 +302,44 @@ def __del__(self): B.delete() +class TestSetOptions: + def test_set_options_basic(self): + @serve.deployment( + num_replicas=4, + max_concurrent_queries=3, + prev_version="abcd", + ray_actor_options={"num_cpus": 2}, + _health_check_timeout_s=17, + ) + def f(): + pass + + f.set_options( + num_replicas=9, + prev_version="abcd", + version="efgh", + ray_actor_options={"num_gpus": 3}, + ) + + assert f.num_replicas == 9 + assert f.max_concurrent_queries == 3 + assert f.prev_version == "abcd" + assert f.version == "efgh" + assert f.ray_actor_options == {"num_gpus": 3} + assert f._config.health_check_timeout_s == 17 + + def test_set_options_validation(self): + @serve.deployment + def f(): + pass + + with pytest.raises(TypeError): + f.set_options(init_args=-4) + + with pytest.raises(ValueError): + f.set_options(max_concurrent_queries=-4) + + if __name__ == "__main__": import sys From 74a29e903a738f115249f02c67dbab18e64a19fd Mon Sep 17 00:00:00 2001 From: shrekris-anyscale <92341594+shrekris-anyscale@users.noreply.github.com> Date: Wed, 16 Mar 2022 20:51:41 -0700 Subject: [PATCH 2/3] Update stability of set_options Co-authored-by: Edward Oakes --- python/ray/serve/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ray/serve/api.py b/python/ray/serve/api.py index e5564ccf9286..a09a7ee6aeb3 100644 --- a/python/ray/serve/api.py +++ b/python/ray/serve/api.py @@ -1260,7 +1260,7 @@ def options( _internal=True, ) - @PublicAPI + @PublicAPI(stability="alpha") def set_options( self, func_or_class: Optional[Callable] = None, From 7437ace60942c233d321970d77b99a0127d60b13 Mon Sep 17 00:00:00 2001 From: Shreyas Krishnaswamy Date: Thu, 17 Mar 2022 14:54:32 -0700 Subject: [PATCH 3/3] Set config directly in set_options --- python/ray/serve/api.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/python/ray/serve/api.py b/python/ray/serve/api.py index a09a7ee6aeb3..05c47dcc4cdd 100644 --- a/python/ray/serve/api.py +++ b/python/ray/serve/api.py @@ -1305,9 +1305,6 @@ def set_options( _health_check_timeout_s=_health_check_timeout_s, ) - self._config.num_replicas = validated._config.num_replicas - self._config.user_config = validated._config.user_config - self._config.max_concurrent_queries = validated._config.max_concurrent_queries self._func_or_class = validated._func_or_class self._name = validated._name self._version = validated._version @@ -1316,15 +1313,7 @@ def set_options( self._init_kwargs = validated._init_kwargs self._route_prefix = validated._route_prefix self._ray_actor_options = validated._ray_actor_options - self._config.autoscaling_config = validated._config.autoscaling_config - self._config.graceful_shutdown_wait_loop_s = ( - validated._config.graceful_shutdown_wait_loop_s - ) - self._config.graceful_shutdown_timeout_s = ( - validated._config.graceful_shutdown_timeout_s - ) - self._config.health_check_period_s = validated._config.health_check_period_s - self._config.health_check_timeout_s = validated._config.health_check_timeout_s + self._config = validated._config def __eq__(self, other): return all(