Skip to content

Commit fb57f55

Browse files
authored
Fix detaching from dstack attach (#2528)
- Do not wait for run status if the run is not expected to have finished. - Catch `KeyboardInterrupt` in more places to avoid printing stack traces.
1 parent c86a092 commit fb57f55

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed

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

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def _command(self, args: argparse.Namespace):
6969
run = self.api.runs.get(args.run_name)
7070
if run is None:
7171
raise CLIError(f"Run {args.run_name} not found")
72+
exit_code = 0
7273
try:
7374
attached = run.attach(
7475
ssh_identity_file=args.ssh_identity_file,
@@ -90,35 +91,36 @@ def _command(self, args: argparse.Namespace):
9091
replica_num=args.replica,
9192
job_num=args.job,
9293
)
93-
try:
94-
for log in logs:
95-
sys.stdout.buffer.write(log)
96-
sys.stdout.buffer.flush()
97-
except KeyboardInterrupt:
98-
pass
94+
for log in logs:
95+
sys.stdout.buffer.write(log)
96+
sys.stdout.buffer.flush()
97+
_print_finished_message_when_available(run)
98+
exit_code = get_run_exit_code(run)
9999
else:
100-
try:
101-
while True:
102-
time.sleep(10)
103-
except KeyboardInterrupt:
104-
pass
100+
while True:
101+
time.sleep(10)
102+
except KeyboardInterrupt:
103+
console.print("\nDetached")
105104
finally:
106105
run.detach()
107106
# TODO: Handle run resubmissions similar to dstack apply
107+
exit(exit_code)
108108

109-
# After reading the logs, the run may not be marked as finished immediately.
110-
# Give the run some time to transition to a finished state before exiting.
111-
for _ in range(30):
112-
run.refresh()
113-
if run.status.is_finished():
114-
print_finished_message(run)
115-
exit(get_run_exit_code(run))
116-
time.sleep(1)
109+
110+
def _print_finished_message_when_available(run: Run) -> None:
111+
# After reading the logs, the run may not be marked as finished immediately.
112+
# Give the run some time to transition to a finished state before exiting.
113+
for _ in range(30):
114+
run.refresh()
115+
if run.status.is_finished():
116+
print_finished_message(run)
117+
break
118+
time.sleep(1)
119+
else:
117120
console.print(
118121
"[error]Lost run connection. Timed out waiting for run final status."
119122
" Check `dstack ps` to see if it's done or failed."
120123
)
121-
exit(1)
122124

123125

124126
_IGNORED_PORTS = [DSTACK_RUNNER_HTTP_PORT]

0 commit comments

Comments
 (0)