Skip to content

Commit d34d776

Browse files
authored
Add CLI deprecation warnings about gateway routers (#3814)
In `dstack ps`, `dstack gateway list`, and `dstack apply` (for runs and gateways).
1 parent c222325 commit d34d776

5 files changed

Lines changed: 56 additions & 0 deletions

File tree

docs/docs/concepts/services.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ Setting the minimum number of replicas to `0` allows the service to scale down t
373373

374374
### PD disaggregation
375375

376+
<!-- NOTE: this section is referenced from the CLI, keep the URL unchanged -->
377+
376378
Since 0.20.17, `dstack` supports serving a model using PD disaggregation. To use it, configure three replica groups: one for a router (for example, [SGLang Model Gateway](https://docs.sglang.io/advanced_features/sgl_model_gateway.html)), one for prefill workers, and one for decode workers.
377379

378380
> Currently, Prefill-Decode disaggregation is supported only for SGLang.

src/dstack/_internal/cli/commands/gateway.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
print_gateways_table,
1818
)
1919
from dstack._internal.core.errors import CLIError, ResourceNotExistsError
20+
from dstack._internal.core.models.gateways import GatewayStatus
2021
from dstack._internal.utils.json_utils import pydantic_orjson_dumps_with_indent
2122
from dstack._internal.utils.logging import get_logger
2223

@@ -108,6 +109,20 @@ def _list(self, args: argparse.Namespace):
108109
raise CLIError("JSON output is not supported together with --watch")
109110

110111
gateways = self.api.client.gateways.list(self.api.project)
112+
deprecated_router_gateways = [
113+
g.name
114+
for g in gateways
115+
if g.status != GatewayStatus.FAILED and g.configuration.router is not None
116+
]
117+
if deprecated_router_gateways and args.format != "json":
118+
logger.warning(
119+
"Specifying `router` in gateway configurations is deprecated"
120+
" and will be disallowed in a future release."
121+
" Please migrate to replica-based routers:"
122+
" https://dstack.ai/docs/concepts/services/#pd-disaggregation"
123+
" (affected gateways: %s)",
124+
", ".join(deprecated_router_gateways),
125+
)
111126
if not args.watch:
112127
if args.format == "json":
113128
print_gateways_json(gateways, project=self.api.project)

src/dstack/_internal/cli/commands/ps.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
console,
1212
)
1313
from dstack._internal.core.errors import CLIError
14+
from dstack._internal.core.models.configurations import ServiceConfiguration
15+
from dstack._internal.utils.logging import get_logger
16+
17+
logger = get_logger(__name__)
1418

1519

1620
class PsCommand(APIBaseCommand):
@@ -64,6 +68,23 @@ def _command(self, args: argparse.Namespace):
6468
raise CLIError("JSON output is not supported together with --watch")
6569

6670
runs = self.api.runs.list(all=args.all, limit=args.last)
71+
deprecated_router_runs = [
72+
run._run.run_spec.run_name
73+
for run in runs
74+
if not run.status.is_finished()
75+
and isinstance(run._run.run_spec.configuration, ServiceConfiguration)
76+
and run._run.run_spec.configuration.router is not None
77+
and run._run.run_spec.run_name is not None
78+
]
79+
if deprecated_router_runs and args.format != "json":
80+
logger.warning(
81+
"Specifying `router` in service configurations is deprecated"
82+
" and will be disallowed in a future release."
83+
" Please migrate to replica-based routers:"
84+
" https://dstack.ai/docs/concepts/services/#pd-disaggregation"
85+
" (affected runs: %s)",
86+
", ".join(deprecated_router_runs),
87+
)
6788
if not args.watch:
6889
if args.format == "json":
6990
run_utils.print_runs_json(self.api.project, runs)

src/dstack/_internal/cli/services/configurators/gateway.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
)
2323
from dstack._internal.core.services.diff import diff_models
2424
from dstack._internal.utils.common import local_time
25+
from dstack._internal.utils.logging import get_logger
2526
from dstack.api._public import Client
2627

28+
logger = get_logger(__name__)
29+
2730

2831
class GatewayConfigurator(BaseApplyConfigurator[GatewayConfiguration]):
2932
TYPE = ApplyConfigurationType.GATEWAY
@@ -40,6 +43,13 @@ def apply_configuration(
4043
configuration=conf,
4144
configuration_path=configuration_path,
4245
)
46+
if spec.configuration.router is not None:
47+
logger.warning(
48+
"Specifying `router` in gateway configurations is deprecated"
49+
" and will be disallowed in a future release."
50+
" Please migrate to replica-based routers:"
51+
" https://dstack.ai/docs/concepts/services/#pd-disaggregation"
52+
)
4353
with console.status("Getting apply plan..."):
4454
plan = _get_plan(api=self.api, spec=spec)
4555
_print_plan_header(plan)

src/dstack/_internal/cli/services/configurators/run.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ def apply_configuration(
101101
if conf.working_dir is not None and not is_absolute_posix_path(conf.working_dir):
102102
raise ConfigurationError("working_dir must be absolute")
103103

104+
if isinstance(conf, ServiceConfiguration) and conf.router is not None:
105+
logger.warning(
106+
"Specifying `router` in service configurations is deprecated"
107+
" and will be disallowed in a future release."
108+
" Please migrate to replica-based routers:"
109+
" https://dstack.ai/docs/concepts/services/#pd-disaggregation"
110+
)
111+
104112
repo = self.get_repo(conf, configuration_path, configurator_args)
105113
if repo is None:
106114
repo = init_default_virtual_repo(api=self.api)

0 commit comments

Comments
 (0)