-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shutdown agents after repl is disconnected #455
Comments
I'm seeing this intermittently also, with lein2. |
Yuck, I was hoping maybe this was a lein1-only thing. Maybe we could add shutdown hooks when launching subprocesses? http://stackoverflow.com/a/272728/495302 I'm kind of guessing wildly, though. |
Do these zombies stay forever, or only 60 seconds (after waiting for the agent thread pool to time out and spin down)? I don't think shutdown hooks run until after the agent pool has shut down? With lein1 we had to call shutdown-agents after the primary client had disconnected. |
Forever in my case at least (I noticed because my laptop was grindingly slow because of the 50 Java processes chewing up resources :( |
A workaround in 1.x is to add |
Actually I can't reproduce this problem either on Leiningen 1 or 2; inside a project or outside. Can you provide more details about your system? |
My Mac is a pretty vanilla Lion:
My Ubuntu VM is running Natty with the Sun VM:
I've checked with a few of my colleagues who are also running Ubuntu, and they don't see this behaviour. The difference seems to be that they're using OpenJDK instead of the Sun version. |
The |
Turns out I can repro this on OpenJDK7, so it's not specific to Oracle's JDK. |
I can reproduce this too. It's really a dream killer. |
...instead of a subprocess, which is the default. refs #455
I can reproduce it inside project folder with lein2: andrew@andrew-u100 ~/dev/clojure/zombie $ java -version
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
Java HotSpot(TM) Client VM (build 22.1-b02, mixed mode)
andrew@andrew-u100 ~/dev/clojure/zombie $ ls -ahl
total 32K
drwxrwxr-x 5 andrew andrew 4.0K 2012-03-24 00:15 .
drwxrwxr-x 4 andrew andrew 4.0K 2012-03-24 00:14 ..
-rw-rw-r-- 1 andrew andrew 98 2012-03-24 00:14 .gitignore
-rw-rw-r-- 1 andrew andrew 265 2012-03-24 00:14 project.clj
-rw-rw-r-- 1 andrew andrew 218 2012-03-24 00:14 README.md
drwxrwxr-x 3 andrew andrew 4.0K 2012-03-24 00:14 src
drwxrwxr-x 3 andrew andrew 4.0K 2012-03-24 00:15 target
drwxrwxr-x 3 andrew andrew 4.0K 2012-03-24 00:14 test
andrew@andrew-u100 ~/dev/clojure/zombie $ ps aux | grep java
andrew 7732 0.0 0.0 4452 772 pts/0 S+ 00:25 0:00 grep --colour=auto java
andrew@andrew-u100 ~/dev/clojure/zombie $ lein2 repl
#<Agent$Closeable$b14108b6@12d0297: {:ss #<ServerSocket ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=56326]>, :transport #<transport$bencode clojure.tools.nrepl.transport$bencode@46d7c4>, :greeting nil, :handler #<session$session$fn__409 clojure.tools.nrepl.middleware.session$session$fn__409@1b7b072>}>
Welcome to REPL-y!
Clojure 1.3.0
Exit: Control+D or (exit) or (quit)
Commands: (help)
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
(sourcery function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Examples from clojuredocs.org:
(clojuredocs name-here)
(clojuredocs "ns-here" "name-here")
nil
user=> Bye for now!
andrew@andrew-u100 ~/dev/clojure/zombie $ ps aux | grep java
andrew 7755 80.8 5.2 387244 53804 pts/0 Sl 00:25 0:24 java -cp /home/andrew/dev/clojure/zombie/test:/home/andrew/dev/clojure/zombie/src:/home/andrew/dev/clojure/zombie/dev-resources:/home/andrew/dev/clojure/zombie/resources:/home/andrew/dev/clojure/zombie/target/classes:/home/andrew/.m2/repository/clojure-complete/clojure-complete/0.2.1/clojure-complete-0.2.1.jar:/home/andrew/.m2/repository/org/apache/httpcomponents/httpcore/4.1.2/httpcore-4.1.2.jar:/home/andrew/.m2/repository/org/apache/httpcomponents/httpclient/4.1.2/httpclient-4.1.2.jar:/home/andrew/.m2/repository/org/clojure/clojure/1.3.0/clojure-1.3.0.jar:/home/andrew/.m2/repository/cheshire/cheshire/2.0.2/cheshire-2.0.2.jar:/home/andrew/.m2/repository/commons-io/commons-io/1.4/commons-io-1.4.jar:/home/andrew/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar:/home/andrew/.m2/repository/clj-http/clj-http/0.2.1/clj-http-0.2.1.jar:/home/andrew/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.8.5/jackson-core-asl-1.8.5.jar:/home/andrew/.m2/repository/org/clojure/tools.nrepl/0.2.0-beta1/tools.nrepl-0.2.0-beta1.jar:/home/andrew/.m2/repository/org/thnetos/cd-client/0.3.3/cd-client-0.3.3.jar:/home/andrew/.m2/repository/commons-codec/commons-codec/1.5/commons-codec-1.5.jar:/home/andrew/.m2/repository/org/codehaus/jackson/jackson-smile/1.8.5/jackson-smile-1.8.5.jar -Dclojure.compile.path=/home/andrew/dev/clojure/zombie/target/classes -Dzombie.version=0.1.0-SNAPSHOT -Dclojure.debug=false clojure.main -e (do (do (require (quote clojure.tools.nrepl.server)) (require (quote complete.core))) nil (do (clojure.core/ns leiningen.core.injected) (defn- compose-hooks [f1 f2] (fn [& args] (apply f2 f1 args))) (defn- join-hooks [original hooks] (reduce compose-hooks original hooks)) (defn- run-hooks [hook original args] (apply (join-hooks original (clojure.core/deref hook)) args)) (defn- prepare-for-hooks [v] (when-not (:robert.hooke/hook (meta (clojure.core/deref v))) (let [hook (atom ())] (alter-var-root v (fn [original] (with-meta (fn [& args] (run-hooks hook original args)) (assoc (meta original) :robert.hooke/hook hook :robert.hooke/original original))))))) (defn- add-unless-present [coll f] (if-not (some #{f} coll) (conj coll f) coll)) (defn add-hook "Add a hook function f to target-var. Hook functions are passed the\n target function and all their arguments and must apply the target to\n the args if they wish to continue execution." [target-var f] (prepare-for-hooks target-var) (swap! (:robert.hooke/hook (meta (clojure.core/deref target-var))) add-unless-present f)) (clojure.core/ns user)) (set! *warn-on-reflection* nil) (do (clojure.tools.nrepl.server/start-server :port 0 :ack-port 48775)))
andrew 7801 0.0 0.0 4456 776 pts/0 S+ 00:26 0:00 grep --colour=auto java
andrew@andrew-u100 ~/dev/clojure/zombie $ Also, in my case there is |
The song and dance with sh/sh-without-orphans is to keep the public fn `sh` unaltered (though maybe it doesn't need to be?). It might be nice to be able to scope the killings to particular eval-in :subprocess calls, e.g. lein repl, but that would take major surgery. In particular, it'd mean adding a parallel set of defmethods to match the other eval-in possibilities. refs #455
In IRC @technomancy, @Raynes, and I had talked about the approach in this latest patch (12e071a), but scoping it to the repl task. In order to do that, I think we'd have to either change the return value semantics of |
Also, I thought a bit more about whether or not subprocesses we launch via |
Oh, I thought the discussion in #leiningen about scoping it to the repl task was about shutting down all subprocesses when a task finishes. If it's about not letting them survive past the entire Leiningen process then I have no problem with it at all; full steam ahead, &c. |
This prevents orphaned processes from shelling out via eval-in :subprocess. The song-and-dance around sh/ sh-without-orphans is to keep the public fn `sh` the same. refs #455
Ah, cool deal. So I've squashed this and put it in master. I'm assuming @Raynes's tweet last night means it worked ;) All: let me know if this fixes things for you guys in lein2 master This should be straightforward to backport to lein1 if we want. |
Can I vote for a fix in Lein 1 please? :-) I've not yet made the switch to 2, and I don't believe that I'm alone... |
No way man, you silly lein 1 users aren't first class citizens anymore. Go away. ;) |
Yeah, I'm planning on releasing a 1.7.1 version with this fixed some time next |
I know I'm probably not supposed to run
Don't know if it should be the same issue as this but it looked quite similar except for the java process hanging around. Checked out sha d7a835efa9d34d8d8cadbd0a4dc7588e22538bd5. |
Did you Ctrl-D to quit |
Yes, I had to use
In summary:
|
OK, can you open a new issue for That line of output you see is normal, though it could probably be made more clear what it means. Thanks! |
Ok, I created #479 for the Thanks. |
Point taken - it would be good to make that more consistent. Opened #480 |
Exiting
lein repl
with ^D leaves a zombiejava
process lying around. This can be replicated as follows:Exiting with ^C instead of ^D does not result in a zombie.
I've observed this on both OSX and Ubuntu.
The text was updated successfully, but these errors were encountered: