Skip to content

Commit 1e46dc5

Browse files
author
Greg Hendershott
committed
Revise REPL and command server startup
People continue to report symptoms like issue #344. In some cases it turned out people needed to update to the latest racket-mode. However at least a couple users on very recent versions reported still seeing the problem intermittently. So: - Simplify code paths by relying on sentinels to do cleanup when the process is deleted or closed. - Rename racket--repl-ensure-buffer-and-process to racket--repl-start, and, it is an error to call it when (racket--repl-live-p) is true. - Rather than setting racket--cmd-proc back to nil, leave it set to the last value, and use things like `process-status` determine if it is 'open. Provide a little helper for this: racket--cmd-open-p. - Wait to start command connect; eliminate racket--cmd-connecting-p state variable. Until we believe the Racket backend has finished starting up and the TCP server would be listening, there is really no point in starting to attempt to connect. Ideally we could know this from a process sentinel, but there is no appropriate event for a comint buffer process. Instead use a comint output filter function to detect first output, e.g. the Welcome to Racket banner. This uses run-at-time to schedule racket--cmd-connect-attempt (should not do directly from a filter function, IIUC). As a result, there is no longer any racket--cmd-connect-start function. Now, we only try to connect to the command server when we first start the REPL process. If the command connection dies thereafter, but the REPL is still alive? Tough beans, users will need to restart the REPL process. Also as a result, I convinced myself that the racket--cmd-connecting-p flag/guard is no longer necessary. Which is good, because it is tricky to make all the code paths manage that properly. I _think_ I finally got that right in a WIP commit. But it's fragile. Some other change, someday, could break this again. Better users get a "can't talk to command server" error, and need to restart the REPL, than have heisenbugs and reports thereof. Note: As before, racket--cmd-connect-attempt will run-at-time itself to retry: We wait until the TCP command server could _possibly_ be ready -- but it's not necessarily ready yet. Although it will probably succeed on the first try, in fact I've seen it occasionally take two attempts while testing this on a laptop/OS that does the startup very quickly. - racket-repl-exit: Use comint-kill-subjob when command server dead - Add defcustom racket-command-startup. - When nil (default): We do not try to start the REPL or the command server automatically; instead we give the user an error message explaining they need to (re)start racket-repl-mode. - When a positive number, we do try to start things automatically and we wait that number of seconds for the command server to connect. While waiting, we remind the user they can C-g to quit waiting.
1 parent 3b8ca60 commit 1e46dc5

10 files changed

+184
-159
lines changed

Reference.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -867,8 +867,18 @@ Pathname of the racket executable.
867867
### racket-command-port
868868
Port number for Racket REPL command server.
869869

870+
### racket-command-startup
871+
What to do when the REPL and command server aren't available to send a command.
872+
873+
- nil: Show an error message explaining that you might need to
874+
start or restart the Racket REPL.
875+
876+
- positive number: Automatically try to start the REPL and wait
877+
that number of seconds for command server to become
878+
available.
879+
870880
### racket-command-timeout
871-
Timeout for Racket REPL command server.
881+
How many seconds to wait for Racket REPL command server responses.
872882

873883
### racket-memory-limit
874884
Terminate the Racket process if memory use exceeds this value in MB.

racket-bug-report.el

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
racket--rkt-source-dir
4848
racket-program
4949
racket-command-port
50+
racket-command-startup
5051
racket-command-timeout
5152
racket-memory-limit
5253
racket-error-context

racket-custom.el

+16-1
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,23 @@
6262
:risky t
6363
:group 'racket)
6464

65+
(defcustom racket-command-startup nil
66+
"What to do when the REPL and command server aren't available to send a command.
67+
68+
- nil: Show an error message explaining that you might need to
69+
start or restart the Racket REPL.
70+
71+
- positive number: Automatically try to start the REPL and wait
72+
that number of seconds for command server to become
73+
available."
74+
:tag "Command Startup"
75+
:type '(choice (const :tag "Safe" nil)
76+
(integer :tag "Auto-start wait seconds" 15))
77+
:risky t
78+
:group 'racket)
79+
6580
(defcustom racket-command-timeout 10
66-
"Timeout for Racket REPL command server."
81+
"How many seconds to wait for Racket REPL command server responses."
6782
:tag "Command Timeout"
6883
:type 'integer
6984
:risky t

racket-edit.el

+5-8
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ commands."
7575
(pcase prefix
7676
(`(4) 'high)
7777
(`(16) 'debug)
78-
(_ racket-error-context))
79-
nil))
78+
(_ racket-error-context))))
8079

8180
(defun racket-run-with-errortrace ()
8281
"Run with `racket-error-context' temporarily set to 'high.
@@ -133,7 +132,7 @@ See also:
133132
(racket--repl-run
134133
mod-path
135134
'coverage
136-
(lambda (_what)
135+
(lambda (_n/a)
137136
(message "Getting coverage results...")
138137
(racket--cmd/async
139138
`(get-uncovered)
@@ -206,7 +205,7 @@ Please keep in mind the following limitations:
206205
(cons (racket--buffer-file-name t) (md5 (current-buffer)))))
207206
(y-or-n-p "Run current buffer first? "))
208207
(racket--repl-run nil nil
209-
(lambda (_what)
208+
(lambda (_n/a)
210209
(racket--do-visit-def-or-mod 'def str)))
211210
(racket--do-visit-def-or-mod 'def str)))))
212211

@@ -238,10 +237,8 @@ See also: `racket-find-collection'."
238237

239238
(defun racket--do-visit-def-or-mod (cmd str)
240239
"CMD must be 'def or 'mod. STR must be `stringp`."
241-
(cl-case major-mode
242-
(racket-mode t)
243-
((racket-repl-mode racket-describe-mode) (racket--repl-ensure-buffer-and-process))
244-
(otherwise (user-error "Requires racket-mode or racket-repl-mode")))
240+
(unless (memq major-mode '(racket-mode racket-repl-mode racket-describe-mode))
241+
(user-error "That doesn't work in %s" major-mode))
245242
(pcase (racket--cmd/await (list cmd str))
246243
(`(,path ,line ,col)
247244
(racket--push-loc)

racket-make-doc.el

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@
146146
'("General"
147147
racket-program
148148
racket-command-port
149+
racket-command-startup
149150
racket-command-timeout
150151
racket-memory-limit
151152
racket-error-context

racket-profile.el

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ delete compiled/*.zo files."
4747
(racket--repl-run
4848
nil
4949
'profile
50-
(lambda (_what)
50+
(lambda (_n/a)
5151
(message "Getting profile results...")
5252
(racket--cmd/async
5353
`(get-profile)

0 commit comments

Comments
 (0)