Repository navigation
[Serve] Reject gang-unaligned autoscaling bounds #67507
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| ReplicaConfig, | ||
| RequestRouterConfig, | ||
| handle_num_replicas_auto, | ||
| validate_gang_scheduling_bounds, | ||
| ) | ||
| from ray.serve._private.usage import ServeUsageTag | ||
| from ray.serve._private.utils import DEFAULT, Default | ||
|
|
@@ -337,6 +338,24 @@ def options( | |
| if max_ongoing_requests is None: | ||
| raise ValueError("`max_ongoing_requests` must be non-null, got None.") | ||
|
|
||
| # Validate the user-provided bounds before handle_num_replicas_auto() | ||
| # merges in defaults, so only explicitly set bounds are checked. | ||
| gang_config_for_validation = ( | ||
| gang_scheduling_config | ||
| if gang_scheduling_config is not DEFAULT.VALUE | ||
| else self._deployment_config.gang_scheduling_config | ||
| ) | ||
| if gang_config_for_validation is not None and autoscaling_config not in [ | ||
| DEFAULT.VALUE, | ||
| None, | ||
| ]: | ||
| if isinstance(gang_config_for_validation, dict): | ||
| gang_size = gang_config_for_validation.get("gang_size") | ||
| else: | ||
| gang_size = gang_config_for_validation.gang_size | ||
| if gang_size is not None: | ||
| validate_gang_scheduling_bounds(gang_size, autoscaling_config) | ||
|
Comment on lines
+341
to
+357
Contributor
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. When calling # Validate the user-provided bounds before handle_num_replicas_auto()
# merges in defaults, so only explicitly set bounds are checked.
gang_config_for_validation = (
gang_scheduling_config
if gang_scheduling_config is not DEFAULT.VALUE
else self._deployment_config.gang_scheduling_config
)
autoscaling_config_for_validation = (
autoscaling_config
if autoscaling_config is not DEFAULT.VALUE
else self._deployment_config.autoscaling_config
)
if (
gang_config_for_validation is not None
and autoscaling_config_for_validation is not None
):
if isinstance(gang_config_for_validation, dict):
gang_size = gang_config_for_validation.get("gang_size")
else:
gang_size = gang_config_for_validation.gang_size
if gang_size is not None:
validate_gang_scheduling_bounds(
gang_size, autoscaling_config_for_validation
)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. Locals pollute user-configured option namesMedium Severity Assigning Additional Locations (1)Reviewed by Cursor Bugbot for commit e54570b. Configure here. |
||
|
|
||
| if num_replicas == "auto": | ||
| max_ongoing_requests, autoscaling_config = handle_num_replicas_auto( | ||
| max_ongoing_requests, autoscaling_config | ||
|
|
||


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.
The
validate_gang_scheduling_boundsfunction signature allowsautoscaling_configto beNone(typed asOptional[Union[Dict, AutoscalingConfig]]). However, ifNoneis passed, the function will bypass theisinstancecheck and execute theelseblock, wherename in autoscaling_configwill raise aTypeError: argument of type 'NoneType' is not iterable. Adding an early return guard forNoneprevents this potential runtime crash.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.
mypy reports:
Both callers already filter out None, so either an early return like the suggestion here, or dropping Optional from the signature, should fix it.