Skip to content

Commit 056d596

Browse files
authored
[serve] move handle options to its own file (#48454)
## Why are these changes needed? Move handle options to `handle_options.py`. Signed-off-by: Cindy Zhang <[email protected]>
1 parent 199b582 commit 056d596

File tree

4 files changed

+92
-87
lines changed

4 files changed

+92
-87
lines changed

python/ray/serve/_private/default_impl.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Callable, Optional, Tuple
1+
from typing import Callable, Optional, Tuple
22

33
import ray
44
from ray._raylet import GcsClient
@@ -17,6 +17,7 @@
1717
DeploymentScheduler,
1818
)
1919
from ray.serve._private.grpc_util import gRPCServer
20+
from ray.serve._private.handle_options import DynamicHandleOptions, InitHandleOptions
2021
from ray.serve._private.replica_scheduler import (
2122
ActorReplicaWrapper,
2223
PowerOfTwoChoicesReplicaScheduler,
@@ -55,15 +56,11 @@ def create_deployment_scheduler(
5556

5657

5758
def create_dynamic_handle_options(**kwargs):
58-
from ray.serve.handle import _DynamicHandleOptions
59-
60-
return _DynamicHandleOptions(**kwargs)
59+
return DynamicHandleOptions(**kwargs)
6160

6261

6362
def create_init_handle_options(**kwargs):
64-
from ray.serve.handle import _InitHandleOptions
65-
66-
return _InitHandleOptions.create(**kwargs)
63+
return InitHandleOptions.create(**kwargs)
6764

6865

6966
def _get_node_id_and_az() -> Tuple[str, Optional[str]]:
@@ -81,13 +78,13 @@ def _get_node_id_and_az() -> Tuple[str, Optional[str]]:
8178

8279

8380
# Interface definition for create_router.
84-
CreateRouterCallable = Callable[[str, DeploymentID, Any], Router]
81+
CreateRouterCallable = Callable[[str, DeploymentID, InitHandleOptions], Router]
8582

8683

8784
def create_router(
8885
handle_id: str,
8986
deployment_id: DeploymentID,
90-
handle_options: Any,
87+
handle_options: InitHandleOptions,
9188
) -> Router:
9289
# NOTE(edoakes): this is lazy due to a nasty circular import that should be fixed.
9390
from ray.serve.context import _get_global_client
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from abc import ABC, abstractmethod
2+
from dataclasses import dataclass, fields
3+
4+
import ray
5+
from ray.serve._private.common import DeploymentHandleSource, RequestProtocol
6+
from ray.serve._private.utils import DEFAULT
7+
8+
9+
@dataclass(frozen=True)
10+
class InitHandleOptionsBase(ABC):
11+
"""Init options for each ServeHandle instance.
12+
13+
These fields can be set by calling `.init()` on a handle before
14+
sending the first request.
15+
"""
16+
17+
_prefer_local_routing: bool = False
18+
_source: DeploymentHandleSource = DeploymentHandleSource.UNKNOWN
19+
20+
@classmethod
21+
@abstractmethod
22+
def create(cls, **kwargs) -> "InitHandleOptionsBase":
23+
raise NotImplementedError
24+
25+
26+
@dataclass(frozen=True)
27+
class InitHandleOptions(InitHandleOptionsBase):
28+
@classmethod
29+
def create(cls, **kwargs) -> "InitHandleOptions":
30+
for k in list(kwargs.keys()):
31+
if kwargs[k] == DEFAULT.VALUE:
32+
# Use default value
33+
del kwargs[k]
34+
35+
# Detect replica source for handles
36+
if (
37+
"_source" not in kwargs
38+
and ray.serve.context._get_internal_replica_context() is not None
39+
):
40+
kwargs["_source"] = DeploymentHandleSource.REPLICA
41+
42+
return cls(**kwargs)
43+
44+
45+
@dataclass(frozen=True)
46+
class DynamicHandleOptionsBase(ABC):
47+
"""Dynamic options for each ServeHandle instance.
48+
49+
These fields can be changed by calling `.options()` on a handle.
50+
"""
51+
52+
method_name: str = "__call__"
53+
multiplexed_model_id: str = ""
54+
stream: bool = False
55+
_request_protocol: str = RequestProtocol.UNDEFINED
56+
57+
def copy_and_update(self, **kwargs) -> "DynamicHandleOptionsBase":
58+
new_kwargs = {}
59+
60+
for f in fields(self):
61+
if f.name not in kwargs or kwargs[f.name] == DEFAULT.VALUE:
62+
new_kwargs[f.name] = getattr(self, f.name)
63+
else:
64+
new_kwargs[f.name] = kwargs[f.name]
65+
66+
return DynamicHandleOptions(**new_kwargs)
67+
68+
69+
@dataclass(frozen=True)
70+
class DynamicHandleOptions(DynamicHandleOptionsBase):
71+
pass

python/ray/serve/handle.py

Lines changed: 8 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,22 @@
33
import logging
44
import time
55
import warnings
6-
from abc import ABC
7-
from dataclasses import dataclass, fields
86
from typing import Any, AsyncIterator, Dict, Iterator, Optional, Tuple, Union
97

108
import ray
119
from ray._raylet import ObjectRefGenerator
12-
from ray.serve._private.common import (
13-
DeploymentHandleSource,
14-
DeploymentID,
15-
RequestMetadata,
16-
RequestProtocol,
17-
)
10+
from ray.serve._private.common import DeploymentID, RequestMetadata, RequestProtocol
1811
from ray.serve._private.constants import SERVE_LOGGER_NAME
1912
from ray.serve._private.default_impl import (
2013
CreateRouterCallable,
2114
create_dynamic_handle_options,
2215
create_init_handle_options,
2316
create_router,
2417
)
18+
from ray.serve._private.handle_options import (
19+
DynamicHandleOptionsBase,
20+
InitHandleOptionsBase,
21+
)
2522
from ray.serve._private.replica_result import ReplicaResult
2623
from ray.serve._private.router import Router
2724
from ray.serve._private.usage import ServeUsageTag
@@ -40,83 +37,23 @@
4037
logger = logging.getLogger(SERVE_LOGGER_NAME)
4138

4239

43-
@dataclass(frozen=True)
44-
class _InitHandleOptionsBase:
45-
"""Init options for each ServeHandle instance.
46-
47-
These fields can be set by calling `.init()` on a handle before
48-
sending the first request.
49-
"""
50-
51-
_prefer_local_routing: bool = False
52-
_source: DeploymentHandleSource = DeploymentHandleSource.UNKNOWN
53-
54-
55-
@dataclass(frozen=True)
56-
class _InitHandleOptions(_InitHandleOptionsBase):
57-
@classmethod
58-
def create(cls, **kwargs) -> "_InitHandleOptions":
59-
for k in list(kwargs.keys()):
60-
if kwargs[k] == DEFAULT.VALUE:
61-
# Use default value
62-
del kwargs[k]
63-
64-
# Detect replica source for handles
65-
if (
66-
"_source" not in kwargs
67-
and ray.serve.context._get_internal_replica_context() is not None
68-
):
69-
kwargs["_source"] = DeploymentHandleSource.REPLICA
70-
71-
return cls(**kwargs)
72-
73-
74-
@dataclass(frozen=True)
75-
class _DynamicHandleOptionsBase(ABC):
76-
"""Dynamic options for each ServeHandle instance.
77-
78-
These fields can be changed by calling `.options()` on a handle.
79-
"""
80-
81-
method_name: str = "__call__"
82-
multiplexed_model_id: str = ""
83-
stream: bool = False
84-
_request_protocol: str = RequestProtocol.UNDEFINED
85-
86-
def copy_and_update(self, **kwargs) -> "_DynamicHandleOptionsBase":
87-
new_kwargs = {}
88-
89-
for f in fields(self):
90-
if f.name not in kwargs or kwargs[f.name] == DEFAULT.VALUE:
91-
new_kwargs[f.name] = getattr(self, f.name)
92-
else:
93-
new_kwargs[f.name] = kwargs[f.name]
94-
95-
return _DynamicHandleOptions(**new_kwargs)
96-
97-
98-
@dataclass(frozen=True)
99-
class _DynamicHandleOptions(_DynamicHandleOptionsBase):
100-
pass
101-
102-
10340
class _DeploymentHandleBase:
10441
def __init__(
10542
self,
10643
deployment_name: str,
10744
app_name: str,
10845
*,
109-
handle_options: Optional[_DynamicHandleOptionsBase] = None,
46+
handle_options: Optional[DynamicHandleOptionsBase] = None,
11047
_router: Optional[Router] = None,
11148
_create_router: Optional[CreateRouterCallable] = None,
11249
_request_counter: Optional[metrics.Counter] = None,
11350
_recorded_telemetry: bool = False,
11451
):
11552
self.deployment_id = DeploymentID(name=deployment_name, app_name=app_name)
116-
self.handle_options: _DynamicHandleOptionsBase = (
53+
self.handle_options: DynamicHandleOptionsBase = (
11754
handle_options or create_dynamic_handle_options()
11855
)
119-
self.init_options: Optional[_InitHandleOptionsBase] = None
56+
self.init_options: Optional[InitHandleOptionsBase] = None
12057

12158
self.handle_id = get_random_string()
12259
self.request_counter = _request_counter or self._create_request_counter(

python/ray/serve/tests/unit/test_handle_options.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import pytest
44

55
from ray.serve._private.common import DeploymentHandleSource, RequestProtocol
6+
from ray.serve._private.handle_options import DynamicHandleOptions, InitHandleOptions
67
from ray.serve._private.utils import DEFAULT
7-
from ray.serve.handle import _DynamicHandleOptions, _InitHandleOptions
88

99

1010
def test_dynamic_handle_options():
11-
default_options = _DynamicHandleOptions()
11+
default_options = DynamicHandleOptions()
1212
assert default_options.method_name == "__call__"
1313
assert default_options.multiplexed_model_id == ""
1414
assert default_options.stream is False
@@ -62,25 +62,25 @@ def test_dynamic_handle_options():
6262

6363

6464
def test_init_handle_options():
65-
default_options = _InitHandleOptions.create()
65+
default_options = InitHandleOptions.create()
6666
assert default_options._prefer_local_routing is False
6767
assert default_options._source == DeploymentHandleSource.UNKNOWN
6868

69-
default1 = _InitHandleOptions.create(_prefer_local_routing=DEFAULT.VALUE)
69+
default1 = InitHandleOptions.create(_prefer_local_routing=DEFAULT.VALUE)
7070
assert default1._prefer_local_routing is False
7171
assert default1._source == DeploymentHandleSource.UNKNOWN
7272

73-
default2 = _InitHandleOptions.create(_source=DEFAULT.VALUE)
73+
default2 = InitHandleOptions.create(_source=DEFAULT.VALUE)
7474
assert default2._prefer_local_routing is False
7575
assert default2._source == DeploymentHandleSource.UNKNOWN
7676

77-
prefer_local = _InitHandleOptions.create(
77+
prefer_local = InitHandleOptions.create(
7878
_prefer_local_routing=True, _source=DEFAULT.VALUE
7979
)
8080
assert prefer_local._prefer_local_routing is True
8181
assert prefer_local._source == DeploymentHandleSource.UNKNOWN
8282

83-
proxy_options = _InitHandleOptions.create(_source=DeploymentHandleSource.PROXY)
83+
proxy_options = InitHandleOptions.create(_source=DeploymentHandleSource.PROXY)
8484
assert proxy_options._prefer_local_routing is False
8585
assert proxy_options._source == DeploymentHandleSource.PROXY
8686

0 commit comments

Comments
 (0)