EDIT Using DISPOSE_ON_CLOSE is not what I'm after, because them I've got the "inverse" problem: the REPL stays alive when I close the JFrame (which is good) but then it also stays alive when launced from outside the REPL (which is bad).
I'm writing a Swing application in Clojure and I find it convenient to both test thing from the REPL (nrepl under Emacs) and from outside the REPL (for example by using lein run or by running the standalone .jar).
When I'm not launching my Swing application from the REPL, I find it convenient to set the default close operation to be EXIT_ON_CLOSE. For example:
(.setDefaultCloseOperation jframe JFrame/EXIT_ON_CLOSE)
So I can click on the JFrame's close button and be done with my app.
However apparently (I may be mistaken on this but I think I'm not seeing things) this is problematic when run from the REPL: as soon as I click on the JFrame's close button I apparently kill the nrepl server and have to reopen a new nrepl.
Knowing that I need to both test from nrepl and from outside any REPL, how can I solve my problem?
Should I "detect" that I'm run from a REPL and then not set the default close operation to exit? Or?
JFrame.EXIT_ON_CLOSE exits the application by calling System.exit() which terminates the currently running Java virtual machine. Since both your application and the REPL run inside the same JVM (since you've started your app from the REPL), this means that the REPL will get killed as well.
Instead, try using:
(.setDefaultCloseOperation jframe JFrame/DISPOSE_ON_CLOSE)
This will also hide (and dispose) the JFrame when you click its close button, but keep your JVM -- and hence your REPL -- running.
Use an environment variable when starting your REPL and choose whether to do dispose on close or exit onclose depending on that variable.
When launch standalone, the variable check would fail and you can thus do exit on close.
Edit:
In the shell:
export REPL_MODE=true ; lein repl
In the clojure code:
(def repl-mode (System/getenv "REPL_MODE"))
(if (not (nil? repl-mode))
; in repl, set to dispose on close
; in standalone mode, set to exit on close
Related
I'm using VS Code to write and debug a C++ program binding to libfuse.
Unfortunately, if you kill a libfuse process with SIGKILL, you then have to use sudo umount -f <mountpoint> before you can start the program again. It's a minor nuisance if I have to do this every time I want to stop or restart debugging, especially as I shouldn't have to authenticate to do such a regular task (the sudo is somehow necessary despite the mount occurring as my user).
While I think this is mainly FUSE's fault (it should gracefully recover from a process being ungracefully killed and unmount automatically instead of leaving the directory saying Transport endpoint is not connected), I also think there should be a way to customise VS Code (or any IDE) to run some clean-up when you want to stop debugging.
I've found that entering -exec signal SIGTERM in the Debug Console will gracefully unmount the directory correctly, stop the process and tell VS Code it's no longer debugging (status bar changes back from orange to blue). But I can't seem to find a way to automate this. I've tried using a .gdbinit file, with some inspiration from this question:
handle SIGTERM nostop
# This doesn't work as hook-quit isn't run when quitting via MI mode, which VS Code uses...
define hook-quit
signal SIGTERM
end
But as noted in the linked question, GDB ignores quit hooks when in MI mode, and VS Code uses MI mode.
The ideal solution for me would be if I could put something in a .vscode configuration file telling it to send -exec signal SIGTERM when I click the stop or restart buttons (and then wait for whatever notification it's getting that debugging has stopped, before restarting if applicable) but I imagine there probably isn't an option for that.
Even if the buttons can't be customised, I'd be happy with the ability to have a keybinding that would just send -exec signal SIGTERM to the Debug Console without me having to open said console and enter the command, though the Command Palette doesn't show anything useful here (nothing that looks like it will send a specified Debug Console command), so I don't expect there's a bindable command for that either.
Does anyone have any suggestions? Or would these belong as feature requests over on the VS Code github? Any way to get GDB to respect its quit hook in MI mode, or to get FUSE to gracefully handle its process being killed would be appreciated too.
I have been playing around with clojurescriptone - neat project - to try and understand how clojurescript works. It is not clear to me how the three components, browser, browser repl and the http server interact.
I use emacs for my development environment
To understand ClojureScript(CS) better I decided to try and port clojurescriptone(CS1) to use lein2 and use nrepl as my repl. The port did work and I was able to get the CS1 environment going and interact with the browser. I prefer - for now - not to start an inferior lisp process to work with the CS repl, but instead run the CS repl within the clojure repl. The only drawback with this is that the CS repl takes input from stdin and emacs prompts me to use stdin. To get around this I am trying to replace some code in CS1 so that it starts the repl from the piggieback library written by Chas Emerick.
In doing so I have reached the limits of my understanding of how these components interact. Apparently from what I can gather the browser repl is a 'server' that listens on some port; while all along I thought it was some sort of client that send requests to the http server and redirected the output to the browser (how??) after evaluating the result. Now I am not certain that is the case.
How do these components interact?
Sorry about the long explanation!!!
Sid
The browser REPL has a sever-side and a client-side. The server-side runs in your main Clojure process; the ClojureScript REPL it self is actually running in the bREPL server.
The bREPL client runs in ClojureScript in the browser, and maintains a long-poll AJAX connection to the server. Whenever you type something in to the REPL on the server, it is compiled to JavaScript and sent to the client via the long-poll mechanism, where it is evaluated in the client an the response sent back.
The server's ClojureScript REPL runs "inside" of your normal Clojure REPL - the exact mechanism for how that works depends on which REPL you're using. nREPL itself runs on a client-server architecture so it's easy to see how things can get confusing.
Does that help at all?
NonStop
Sets nonstop mode. If a terminal's already been set up, it's too late;
the debugger remembers the setting in case you restart, though. (source)
When is it useful,why do I need to debug if it doesn't ever stop?
As I understand it, you can use the debugger in rendez-vous-mode. In this setting, the debugger runs the application NonStop without a tty first, but when an event interrupt occurs, it stops the application and sets the tty up for you to debug.
Update: Rendez-vous-Mode is useful for attaching to a running perl process after it has been started (by something out of your control). If your application is prepared for dynamically loading the debugger, you can enter the debugger even if you did not start it with a -d option at all.
Is there any way to kill an Eclipse background operation without killing Eclipse itself?
Specifically, I want to kill stalled Subclipse SVN operations. Clicking 'cancel' pops up a little Cancel Requested message, but the operation still sits there forever blocking everything else.
This is Eclipse Helios on Windows 7 if that makes any difference.
I was able to unstuck Eclipse (it was stuck on a large file diff) using the following steps.
Preparations: I always start Eclipse with the eclipse-console: Add start parameter -console in eclipse.ini (first line)
The console always remains responsive even when the eclipse UI freezes
I found the following commands in the console: help threads
List all threads: threads
Stop a thread: threads stop THREAD-NAME
UPDATE: I found out, that usually the "main" thread causes the freezing. Thus the solution is:
Type this in the eclipse console:
threads stop main
This will trigger/throw an Exception in that thread, effectively interrupting what it was doing (being stuck).
This might cause other side-effects (depending on what action was interrupted and where), but i had no problems with it so far.
Killing the task from the Progress window (Window->Show View->Other|General->Progress or Alt+Shift+Q, Q | General->Progress).
Then choose the offending thread and click the red square.
Note it sometimes takes a delay before the kill occur, you may also have to kill other thread in there to get what you want. Lastly it does not always work, if this fails I usually just restart eclipse.
Hope this helps
I was able to stop/terminate the hanging SVN commit process by briefly disconnecting the network adapter. This saved me from killing the Eclipse process, which if not terminated gracefully is known to cause other headaches.
If you go to window Progress in Eclipse and click red square to Stop:
and next, red square becomes gray square and process i frozen (Cancel Requested):
You must use Task Manager (Alt+Ctrl+Del on Windows) for kill process. Go to tab Processes, find process javaw.exe* and click End Process.
The result: frozen process in Eclipse was closed but your Eclipse wasn't closed.
* Process with name javaw.exe is for WildFly server. For Subclipse SVN can be another name of proces.
I'm not sure, but from the Debug perspective, you may be able to view the thread that's performing the background operation and kill it from there for quicker exit.
In console window, open "Open OSGi Console" from drop button.
In this console you can type command threads. This will show all running threads.
You can kill process with command threads stop '<Process name>'. Remember to use single apostrophe ' surrounding <Process name>, otherwise it won't work.
For example, I had to type:
threads stop 'Worker-12: Refresh DSLD scripts'
I had a problem where the external compiler I was using froze up when I tried to cancel the build operation. It was stuck in the "Cancel Requested" state. I went to the Windows Task Manager and found my compiler process and terminated it. That allowed Eclipse to continue and successfully cancel the operation.
Keep clicking on clean console, it will show the back ground processes, keep killing one by one.
I made this by opening console in eclipse and typing 'threads'. And then 'threads stop thread-name'.
In Lunux you can list all the Eclipse processes
ps -edf | grep eclipse
Then you choose the child process (the backgound doing Java process) of the main process (the Eclipse GUI Java process) of the starting shell process.
Example:
myself 21821 1222 0 09:28 ? 00:00:00 /local/eclipse/jee-2021-06/eclipse
myself 21839 21821 8 09:28 ? 00:24:53 /usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java -Dosgi.requiredJavaVersion=11 -Dosgi.instance.area.default=#user.home/eclipse-workspace ... much more ...
myself 21965 21839 0 09:29 ? 00:01:48 /usr/lib/jvm/java-11-openjdk-amd64/bin/java -cp /local/eclipse/jee-2021-06/eclipse/../../../../home/myself/.p2/pool/p ... much more ...
The child in the chain of processes is the one with the proc-id 21965. This one you have to kill.
Try kill -2 <proc-id> and, if it did not work, kill -9 <procid>
I am trying to find a hook in Emacs, which should fire right before emacs server graceful shutdown.
I tried kill-emacs-query-functions, kill-emacs-hook, server-done-hook with elisp like :
(add-hook 'server-done-hook
'(lambda ()
(savehist-save)
)
)
... but none of them is called when OS shuts down, so history is not saved.
Maybe someone could give a hint?
P.S. I am on Gentoo Linux, emacs-vcs-23.2.9999 package, terminal only. For testing desired behaviour Emacs is stopped using start-stop-daemon utility.
Since Emacs 24.1, Emacs runs kill-emacs which runs the functions in kill-emacs-hook. So the question, and the rest of this answer, are only relevant to older versions.
The right place to run something before Emacs shuts down is either kill-emacs-query-function if you want to be able to cancel the shutdown or kill-emacs-hook if you don't. The problem you're facing is that your OS does not notify Emacs to shut down gracefully in a way that Emacs understands, or to look at it the other way, Emacs does not understand your OS's request to suht down gracefully.
A graceful way of shutting down Emacs 23 from the outside is to run emacsclient -n -e '(kill-emacs)'. That's obviously not a generic way of telling a program to shut down gracefully.
The normal way to shut down a process gracefully on unix is to send it a SIGHUP or SIGTERM signal. Unfortunately, Emacs treats almost all signals as fatal, and only runs an emergency auto save and no lisp code when it receives them. This is not configurable from lisp. A different behavior has been requested, but turned down.
A partial workaround (found here) is to run session saving hooks in delete-frame-functions. This hook is likely to be run before the system shutdown sequence, either when you close your last frame or when the X server dies (taking your terminals with them if you run Emacs in a terminal). Make sure you don't run the hook that kills the server in delete-frame-functions.
By the way, if you were going to use this exact hook, note that your code is a complicated way of writing (add-hook 'server-done-hook 'savehist-save), and that's not useful since there's already savehist-autosave in kill-emacs-hook.