-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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] Reconfigure backend class at runtime #11709
[Serve] Reconfigure backend class at runtime #11709
Conversation
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.
Looks good at a high level to me. Can we mark this as experimental or something like that for now? Just have a note in the docs.
@@ -34,3 +34,6 @@ | |||
2000, | |||
5000, | |||
] | |||
|
|||
#: Name of backend reconfiguration method implemented by user. | |||
BACKEND_RECONFIGURE_METHOD = "reconfigure" |
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.
shouldn't this be user_reconfigure
?
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.
Sure, I forgot we had picked that name but that name makes sense
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.
Oh I don't think we settled on a name, that's just the method I saw in other places in this PR
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.
Ah I see. Before I had user_reconfigure
as our internal method and reconfigure
as the name of the method the user provides in the class. I think I'll just make them both reconfigure
for consistency.
python/ray/serve/api.py
Outdated
@@ -249,6 +257,10 @@ def create_backend( | |||
update={"internal_metadata": metadata}) | |||
else: | |||
raise TypeError("config must be a BackendConfig or a dictionary.") | |||
if backend_config.user_config and not inspect.isclass(func_or_class): |
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.
let's also make sure reconfigure
is a method in the class so user get this error immediately.
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.
Sounds good, we do that check in backend_worker
currently. That way, it's checked upon calling create_backend
, as well as upon calling update_backend_config
. I will move the inspect.isclass
check into backend_worker
as well, since that should also happen for both create_backend
and update_backend_config
.
python/ray/serve/config.py
Outdated
""" | ||
|
||
internal_metadata: BackendMetadata = BackendMetadata() | ||
num_replicas: PositiveInt = 1 | ||
max_batch_size: Optional[PositiveInt] = None | ||
batch_wait_timeout: float = 0 | ||
max_concurrent_queries: Optional[int] = None | ||
user_config: Dict[str, Any] = None |
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.
this should just be Any instead of Dict? Because we are just passing this to user's method directly.
@@ -48,6 +48,42 @@ def function(flask_request): | |||
assert resp == "POST" | |||
|
|||
|
|||
def test_backend_user_config(serve_instance): | |||
client = serve_instance | |||
|
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.
let's use SignalActor to synchronize this instead of sending 100 queries
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.
@simon-mo Actually I'm not sure about this--I don't think we need any synchronization here, we just want a way of asking each replica if it got updated. Since replicas are called in round-robin, it's enough to call handle.remote()
three (or 100) times, and these calls don't have to happen simultaneously. Does that make sense?
If we did want to use SignalActor, I'm not sure how that would work, since we don't have a "handle" for each replica, we just have one for the endpoint.
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.
Good point.
@architkulkarni ah, looks like there are some conflicts now. Mind resolving them so we can merge? |
Allows a user to add a
reconfigure
method to their backend class, and then update (all current and future replicas of) their backend by setting theuser_config
field in theBackendConfig
, which gets passed to theirreconfigure
method. The following example from the doc should make the usage clear:Why are these changes needed?
Related issue number
Checks
scripts/format.sh
to lint the changes in this PR.