Let's assume for a moment that, for some strange reason, the "directory watching" strategy won't work here. Does anyone have any other suggestions? I am thinking there must be a simple way to setup Jenkins and Supervisord to run these apps, but what I'm doing keeps getting more and more complex, which is typically a warning sign that I'm on the wrong track.
On Saturday, August 8, 2015 at 5:24:28 PM UTC-4, Lawrence Krubner wrote: > > I feel stupid, but I have not been able to track this down. > > The background is that I have Jenkins running on the server, and when > triggered it pulls code from Github, compiles it, and then moves the final > uberjar to the directory where I keep all the uberjars that run on this > server. Then I have an app that should kill all currently running > instances. Then Supervisord should step in and restart the instances, using > the new uberjars for the new instances. > > All of this works, but I have been doing one bit by hand: "kill all > currently running instances". I log in as root and run a script that kills > the old instances. But just today I wrote a quick Clojure app to automate > this for me (the whole app is 50 lines of code, so this is a very small > app). > > To trigger the main action, I thought the app should set a watcher on the > final directory where Jenkins moves the uberjars to. When Jenkins moves a > new uberjar to the directory, the watch would be triggered and then it > could run the "kill all currently running instances" script. However, I > assumed that the ""kill all currently running instances"" script would be > triggered once each time the uberjar was updated, but instead it seems to > be triggered infinitely. Does a JVM app, or a Clojure app, change the dir > its in, on launch? Or is the problem in my own code? I'm using Chris > Zheng's excellent Hara library for the Watch. This is the main function of > my app, which is called on startup: > > (defn establish-watchers [] > "The config contains a hashmap which has a 'watchers' key, which > contains a vector that holds hashmaps with 2 keys, one pointing to the > directory that should be watched and the other pointing to the command that > should be run when the watch is triggered." > (let [config (read-string (slurp "/etc/fiit.edn")) > watchers (:watchers config)] > (doseq [w watchers] > (common-watch/add (clojure.java.io/file (:dir-to-watch w)) (keyword > (:dir-to-watch w)) > (fn [f k _ [cmd file]] > (pprint/pprint (:out (sh/sh (:action-to-do w))))) > {:types #{:create :modify} > :recursive false > :async false})))) > > So if I log in as root and start the app like this: > > /usr/bin/java -jar /home/jenkins/fiit/fiit-1-standalone.jar > > Then at the terminal I see this, which I expect: > > [/home/jenkins/sarr] > [/home/jenkins/food_for_all] > > Those are the 2 directories that it is watching. > > Then if I trigger Jenkins for the sarr app, Jenkins will pull the sarr > code from Github, rebuild the sarr uberjar, and move the uberjar to > /home/jenkins/sarr. > > All of that works just great. And then my app sees there has been a change > in /home/jenkins/sarr, and so it calls the command to kill all existing > instances of the sarr app. However, instead of doing this once, it starts > doing so an infinite number of times. At the terminal I see: > > (sarr is a Java app, not a Clojure app) > > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \nroot 25593 0.0 0.1 5813460 19452 ? > Sl 20:28 0:00 /usr/bin/java -cp /home/jenkins/sarr/sarr.jar > com.candle.sarr.Main\nroot 25595 0.0 0.1 5813460 19564 ? Sl > 20:28 0:00 /usr/bin/java -cp /home/jenkins/sarr/sarr.jar > com.candle.sarr.Main\n25593\n25595\n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n25694\n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \nroot 26239 0.0 0.1 5813460 19452 ? > Sl 20:28 0:00 /usr/bin/java -cp /home/jenkins/sarr/sarr.jar > com.candle.sarr.Main\n26239\n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \nroot 26319 0.0 0.1 5811252 15484 ? > Sl 20:28 0:00 /usr/bin/java -cp /home/jenkins/sarr/sarr.jar > com.candle.sarr.Main\n26319\n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > "We will kill these processes: \n" > > > I have Supervisord set to run 3 instances of the sarr app, so you can see > at first it it is killing these PIDs: > > 25593 > 25595 > 25694 > > Supervisord restarts these almost instantly, so you can see these > processes are launched and instantly killed, all on the same line of > output: > > "We will kill these processes: \nroot 26239 0.0 0.1 5813460 19452 ? > Sl 20:28 0:00 /usr/bin/java -cp /home/jenkins/sarr/sarr.jar > com.candle.sarr.Main\n26239\n" > > "We will kill these processes: \nroot 26319 0.0 0.1 5811252 15484 ? > Sl 20:28 0:00 /usr/bin/java -cp /home/jenkins/sarr/sarr.jar > com.candle.sarr.Main\n26319\n" > > This goes on for as long as I allow it (it takes Supervisord a long time > to quit, because when I am developing new software, I set startretries=500, > in Supervisord, exactly so I can experiment like this). > > I looked here to try to figure out what was going on: > > > https://github.com/zcaudate/hara/blob/55b4eda688a4e616f03bf3740419a69b5c5dd658/src/hara/io/watch.clj > > As near as I can tell, the main action happens here: > > (defn run-watcher [watcher] > (let [^java.nio.file.WatchKey wkey > (.take ^java.nio.file.WatchService (:service watcher))] > (doseq [^java.nio.file.WatchEvent event (.pollEvents wkey) > :when (not= (.kind event) > StandardWatchEventKinds/OVERFLOW)] > (let [kind (.kind event) > ^java.nio.file.Path path (.watchable wkey) > ^java.nio.file.Path context (.context event) > ^java.nio.file.Path res-path (.resolve path context) > ^java.io.File file (.toFile res-path)] > (if (and (= kind StandardWatchEventKinds/ENTRY_CREATE) > (.isDirectory file) > (-> watcher :options :recursive)) > (register-sub-directory watcher (.getPath file))) > (if (.isFile file) > (process-event watcher kind file)))) > (.reset wkey) > (recur watcher))) > > > Again, maybe I am being stupid, but it looks to me like the callback is > called once per event triggered on that directory. So why would the > callback seem to be called an infinite number of times? Does starting or > stopping the app trigger a change in the directory (thus triggering the > callback again)? > > > > > > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.