Hi
If I connect to a swank server starting simply with:
(require :swank) (swank:create-server :port 4095 :dont-close t)
and evaluate an output producing form such as:
(loop (format t "~S~%" *standard-output*) (sleep 2))
then the output is printed to the repl, but after disconnecting and connecting again the output no longer makes it there. This is seemingly regardless of the value of *GLOBALLY-REDIRECT-IO* (set in ~/.swank.lisp) which is contradicting the documentation at
https://common-lisp.net/project/slime/doc/html/Global-IO-Redirection.html
Is there a way to get standard streams redirected to the new repl upon reconnect?
Thanks, Gabor
On Sun, Nov 22, 2015 at 10:46 PM, Gábor Melis mega@retes.hu wrote:
Is there a way to get standard streams redirected to the new repl upon reconnect?
This works for me on SBCL 1.2.12. On ACL 10, I don't see redirection going on at all, which is weird, since I'm pretty sure it that used to work. What Lisp are you using?
Luís Oliveira luismbo@gmail.com writes:
On Sun, Nov 22, 2015 at 10:46 PM, Gábor Melis mega@retes.hu wrote:
Is there a way to get standard streams redirected to the new repl upon reconnect?
This works for me on SBCL 1.2.12. On ACL 10, I don't see redirection going on at all, which is weird, since I'm pretty sure it that used to work. What Lisp are you using?
This was on SBCL. Sorry for omitting that detail.
On Mon, Nov 23, 2015 at 9:44 AM, Gábor Melis mega@retes.hu wrote:
This was on SBCL. Sorry for omitting that detail.
It's working for me on SBCL 1.3.0 and latest SLIME. Let's try and codify the test case a bit further to see if we can find what differs between our setups.
SBCL side:
$ echo "(defparameter swank:*globally-redirect-io* t)" > ~/.swank.lisp $ sbcl --eval '(require :swank)' \ --eval '(swank:create-server :port 4095 :dont-close t)' \ --eval '(loop (format t "~S~%" *standard-output*) (sleep 2))' This is SBCL 1.3.0, an implementation of ANSI Common Lisp. More information about SBCL is available at http://www.sbcl.org/.
SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. ;; Swank started at port: 4095. #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDOUT* {912A129}> #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDOUT* {912A129}>
[ .. and so on ..]
Emacs side:
$ emacs -q --eval "(add-to-list 'load-path "~/src/lisp/slime")" \ --eval "(setq slime-contribs '(slime-repl))" \ --eval "(require 'slime)" \ --eval "(slime-connect "127.0.0.1" 4095)"
And I get this on the REPL:
#<SYNONYM-STREAM :SYMBOL SWANK::*CURRENT-STANDARD-OUTPUT* {B87C301}>
After `M-x slime-disconnect', I get this on SBCL:
;; swank:close-connection: end of file on #<SB-SYS:FD-STREAM for "socket 127.0.0.1:4095, peer: 127.0.0.1:58832" {B54FB29}> #<SYNONYM-STREAM :SYMBOL SWANK::*CURRENT-STANDARD-OUTPUT* {B87C301}>
Running the emacs command again gets me the same output in the REPL. Were you doing anything different?
Random question: do you have :SB-THREAD in your *FEATURES*?
Cheers,
On Mon, Nov 23, 2015 at 3:53 PM, Luís Oliveira luismbo@gmail.com wrote:
On Mon, Nov 23, 2015 at 9:44 AM, Gábor Melis mega@retes.hu wrote:
This was on SBCL. Sorry for omitting that detail.
It's working for me on SBCL 1.3.0 and latest SLIME. Let's try and codify the test case a bit further to see if we can find what differs between our setups.
SBCL side:
$ echo "(defparameter swank:*globally-redirect-io* t)" > ~/.swank.lisp $ sbcl --eval '(require :swank)' \ --eval '(swank:create-server :port 4095 :dont-close t)' \ --eval '(loop (format t "~S~%" *standard-output*) (sleep 2))' This is SBCL 1.3.0, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>. SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. ;; Swank started at port: 4095. #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDOUT* {912A129}> #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDOUT* {912A129}> [ .. and so on ..]
Emacs side:
$ emacs -q --eval "(add-to-list 'load-path \"~/src/lisp/slime\")" \ --eval "(setq slime-contribs '(slime-repl))" \ --eval "(require 'slime)" \ --eval "(slime-connect \"127.0.0.1\" 4095)"
And I get this on the REPL:
#<SYNONYM-STREAM :SYMBOL SWANK::*CURRENT-STANDARD-OUTPUT* {B87C301}>
After `M-x slime-disconnect', I get this on SBCL:
;; swank:close-connection: end of file on #<SB-SYS:FD-STREAM for
"socket 127.0.0.1:4095, peer: 127.0.0.1:58832" {B54FB29}> #<SYNONYM-STREAM :SYMBOL SWANK::*CURRENT-STANDARD-OUTPUT* {B87C301}>
Running the emacs command again gets me the same output in the REPL. Were you doing anything different?
Yes, the above works. It also works if I start a thread from the Slime repl like this:
(sb-thread:make-thread (lambda () (loop (format t "~S~%" *standard-output*) (sleep 2))))
On the other hand, if I evaluate the loop from a lisp buffer such as *slime-scratch* then it doesn't. So start sbcl like this:
$ echo "(defparameter swank:*globally-redirect-io* t)" > ~/.swank.lisp $ sbcl --eval '(require :swank)' \ --eval '(swank:create-server :port 4095 :dont-close t)'
Start slime exactly as you did:
$ emacs -q --eval "(add-to-list 'load-path "~/src/lisp/slime")" \ --eval "(setq slime-contribs '(slime-repl))" \ --eval "(require 'slime)" \ --eval "(slime-connect "127.0.0.1" 4095)"
Then switch to *slime-scratch* and evaluate with C-x C-e the loop form. The output goes to the repl regardless of *globally-redirect-io*. Now disconnect, reconnect and there is no more output although the thread is still there.
Random question: do you have :SB-THREAD in your *FEATURES*?
Yes.
On Mon, Nov 23, 2015 at 4:18 PM, Gábor Melis mega@retes.hu wrote:
Then switch to *slime-scratch* and evaluate with C-x C-e the loop form. The output goes to the repl regardless of *globally-redirect-io*. Now disconnect, reconnect and there is no more output although the thread is still there.
Right, so what happens in that scenario is that a thread is spawned via SWANK::SPAWN-WORKER-THREAD to handle the C-x C-e request and eventually calls SWANK::WITH-IO-REDIRECTION which will bind the various stream variables to the specific REPL stream created for the current connection.
I've attached a tentative fix for your use case.
I'll have to think a little bit about the broader implications. Can you tell me a bit more about how your use case came about? That might help.
Cheers,
Luís Oliveira luismbo@gmail.com writes:
On Mon, Nov 23, 2015 at 4:18 PM, Gábor Melis mega@retes.hu wrote:
Then switch to *slime-scratch* and evaluate with C-x C-e the loop form. The output goes to the repl regardless of *globally-redirect-io*. Now disconnect, reconnect and there is no more output although the thread is still there.
Right, so what happens in that scenario is that a thread is spawned via SWANK::SPAWN-WORKER-THREAD to handle the C-x C-e request and eventually calls SWANK::WITH-IO-REDIRECTION which will bind the various stream variables to the specific REPL stream created for the current connection.
I've attached a tentative fix for your use case.
Thank you, I'll test it tomorrow.
I'll have to think a little bit about the broader implications. Can you tell me a bit more about how your use case came about? That might help.
I had a couple of uncommented forms at the bottom a file to evaluate which I did. Since it takes several days for the computation to finish, my laptop on which Slime ran went to sleep and I had to slime-connect again on resume.
In general, I almost never use the REPL and tend to evaluate stuff from buffers. I didn't even realize that forms evaluated at the REPL don't have this problem until testing it yesterday.
mega@retes.hu (Gábor Melis) writes:
Luís Oliveira luismbo@gmail.com writes:
On Mon, Nov 23, 2015 at 4:18 PM, Gábor Melis mega@retes.hu wrote:
Then switch to *slime-scratch* and evaluate with C-x C-e the loop form. The output goes to the repl regardless of *globally-redirect-io*. Now disconnect, reconnect and there is no more output although the thread is still there.
Right, so what happens in that scenario is that a thread is spawned via SWANK::SPAWN-WORKER-THREAD to handle the C-x C-e request and eventually calls SWANK::WITH-IO-REDIRECTION which will bind the various stream variables to the specific REPL stream created for the current connection.
I've attached a tentative fix for your use case.
Thank you, I'll test it tomorrow.
Seems to work fine.
On Tue, Nov 24, 2015 at 9:34 PM, Gábor Melis mega@retes.hu wrote:
Seems to work fine.
One thing that didn't work is that we need to always redirection *STANDARD-INPUT* since *GLOBALLY-REDIRECT-IO* doesn't affect that. Pushed an improved fix.
Cheers,
mega@retes.hu (Gábor Melis) writes:
Hi
If I connect to a swank server starting simply with:
(require :swank) (swank:create-server :port 4095 :dont-close t)
and evaluate an output producing form such as:
(loop (format t "~S~%" *standard-output*) (sleep 2))
then the output is printed to the repl, but after disconnecting and connecting again the output no longer makes it there. This is seemingly regardless of the value of *GLOBALLY-REDIRECT-IO* (set in ~/.swank.lisp) which is contradicting the documentation at
https://common-lisp.net/project/slime/doc/html/Global-IO-Redirection.html
Is there a way to get standard streams redirected to the new repl upon reconnect?
AFAIK, there's no global variable holding the slime streams. They're bound to in local lexical variables.
Is the looping thread still running after disconnecting? I would expect it to be killed by the disconnection.
If *standard-output* wasn't the slime stream itself, but a CL redirecting stream, I don't know that CL implementations block threads trying to do I/O on them until the base thread is again available for I/O.
I'm not saying that what you want is impossible, just that it'd require more sophisticated (and more interesting to implement) mechanisms than currently available.
Hi! I had some problems with trace. Sometimes trace to some functions (especially to those in implementation of SWANK itself) didn't appear on the screen.
Maybe I just didn't read manual carefully, but I solved my problem with this:
; catch initial value of *standard-output* - that is, output to original plain SBCL console. (defvar *initial-standard-output* *standard-output*)
; make sure that code is invoked every time we connect to SWANK.
(defun redirect-trace-output-to-inferior-lisp (c) (setf (slot-value c 'swank::trace-output) *initial-standard-output*))
(push 'redirect-trace-output-to-inferior-lisp swank::*new-connection-hook*)
somewhere in my initialization file. Now I'm sure all trace output is directed to plain SBCL console.
Maybe you could implement what you need in a way like this.
Disclaimer: my swank client is not EMACS. But AFAIR this worked in EMACS too.