-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Serve] Use Async Handle for DAG Execution #27411
Merged
Merged
Changes from 9 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
f307797
wip async handle for dag execution
simon-mo 89772db
allow gather
simon-mo 0ad1f66
wip
simon-mo 1518f20
handle multiple await
simon-mo e67cc13
unused import
simon-mo fa0bb37
Merge branch 'master' of github.com:ray-project/ray into serve/async-dag
simon-mo 4429d54
comments
simon-mo ed219a6
lint
simon-mo 53748f0
new line
simon-mo 94c5c5f
fix
simon-mo 644dbaa
change objects to list again
simon-mo 2850bb9
fix list
simon-mo bf7b589
minor grammar
simon-mo f9e5441
wip
simon-mo 9514826
wip
simon-mo 3c74dde
pass tests!
simon-mo 564aeb9
rename RayServeLazyAsyncHandle -> RayServeDeploymentHandle
simon-mo 862ac79
feature flag old behavior as escape hatch
simon-mo 370166f
lint
simon-mo aaf7957
split the doc change
simon-mo 1636da9
Merge branch 'master' of github.com:ray-project/ray into serve/async-dag
simon-mo c401823
fix tests
simon-mo File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from weakref import WeakValueDictionary | ||
import ray | ||
|
||
import io | ||
|
@@ -12,16 +13,19 @@ | |
else: | ||
import pickle # noqa: F401 | ||
|
||
from typing import List, Dict, Any, TypeVar | ||
from typing import Generic, List, Dict, Any, Type, TypeVar | ||
from ray.dag.base import DAGNodeBase | ||
|
||
T = TypeVar("T") | ||
|
||
# Used in deserialization hooks to reference scanner instances. | ||
_instances: Dict[int, "_PyObjScanner"] = {} | ||
|
||
# Generic types for the scanner to transform from and to. | ||
SourceType = TypeVar("SourceType") | ||
TransformedType = TypeVar("TransformedType") | ||
|
||
def _get_node(instance_id: int, node_index: int) -> DAGNodeBase: | ||
|
||
def _get_node(instance_id: int, node_index: int) -> SourceType: | ||
"""Get the node instance. | ||
|
||
Note: This function should be static and globally importable, | ||
|
@@ -30,50 +34,78 @@ def _get_node(instance_id: int, node_index: int) -> DAGNodeBase: | |
return _instances[instance_id]._replace_index(node_index) | ||
|
||
|
||
class _PyObjScanner(ray.cloudpickle.CloudPickler): | ||
"""Utility to find and replace DAGNodes in Python objects. | ||
def _get_object(instance_id: int, node_index: int) -> Any: | ||
"""Used to get arbitrary object other than SourceType. | ||
|
||
Note: This function should be static and globally importable, | ||
otherwise the serialization overhead would be very significant. | ||
""" | ||
return _instances[instance_id]._objects[node_index] | ||
|
||
|
||
class _PyObjScanner(ray.cloudpickle.CloudPickler, Generic[SourceType, TransformedType]): | ||
"""Utility to find and replace the `source_type` in Python objects. | ||
|
||
This uses pickle to walk the PyObj graph and find first-level DAGNode | ||
instances on ``find_nodes()``. The caller can then compute a replacement | ||
table and then replace the nodes via ``replace_nodes()``. | ||
|
||
Args: | ||
source_type: the type of object to find and replace. Default to DAGNodeBase. | ||
""" | ||
|
||
def __init__(self): | ||
def __init__(self, source_type: Type = DAGNodeBase): | ||
self.source_type = source_type | ||
# Buffer to keep intermediate serialized state. | ||
self._buf = io.BytesIO() | ||
# List of top-level DAGNodes found during the serialization pass. | ||
# List of top-level SourceType found during the serialization pass. | ||
self._found = None | ||
# List of other objects found during the serializatoin pass. | ||
# This is used to store references to objects so they won't be | ||
# serialized by cloudpickle. | ||
self._objects = WeakValueDictionary() | ||
# Replacement table to consult during deserialization. | ||
self._replace_table: Dict[DAGNodeBase, T] = None | ||
self._replace_table: Dict[SourceType, TransformedType] = None | ||
_instances[id(self)] = self | ||
super().__init__(self._buf) | ||
|
||
def reducer_override(self, obj): | ||
"""Hook for reducing objects.""" | ||
if isinstance(obj, DAGNodeBase): | ||
"""Hook for reducing objects. | ||
|
||
The function intercepts serialization of all objects and store them | ||
to internal data structures, preventing actually writing them to | ||
the buffer. | ||
""" | ||
if obj is _get_object or obj is _get_object: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. duplicate |
||
# Only fall back to cloudpickle for these two functions. | ||
return super().reducer_override(obj) | ||
elif isinstance(obj, self.source_type): | ||
index = len(self._found) | ||
self._found.append(obj) | ||
return _get_node, (id(self), index) | ||
else: | ||
index = len(self._objects) | ||
self._objects.append(obj) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how do we do the dict object to do append? |
||
return _get_object, (id(self), index) | ||
|
||
return super().reducer_override(obj) | ||
|
||
def find_nodes(self, obj: Any) -> List[DAGNodeBase]: | ||
def find_nodes(self, obj: Any) -> List[SourceType]: | ||
"""Find top-level DAGNodes.""" | ||
assert ( | ||
self._found is None | ||
), "find_nodes cannot be called twice on the same PyObjScanner instance." | ||
self._found = [] | ||
self._objects = [] | ||
self.dump(obj) | ||
return self._found | ||
|
||
def replace_nodes(self, table: Dict[DAGNodeBase, T]) -> Any: | ||
def replace_nodes(self, table: Dict[SourceType, TransformedType]) -> Any: | ||
"""Replace previously found DAGNodes per the given table.""" | ||
assert self._found is not None, "find_nodes must be called first" | ||
self._replace_table = table | ||
self._buf.seek(0) | ||
return pickle.load(self._buf) | ||
|
||
def _replace_index(self, i: int) -> DAGNodeBase: | ||
def _replace_index(self, i: int) -> SourceType: | ||
return self._replace_table[self._found[i]] | ||
|
||
def __del__(self): | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.