geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jdil...@apache.org
Subject svn commit: r509100 - /geronimo/sandbox/build-support/libraries/system/1/groovy/gbuild/system/util/BastardChildReaper.groovy
Date Mon, 19 Feb 2007 06:07:30 GMT
Author: jdillon
Date: Sun Feb 18 22:07:29 2007
New Revision: 509100

URL: http://svn.apache.org/viewvc?view=rev&rev=509100
Log:
Whipped up something to kill off any bastard children that linger after builds run

Added:
    geronimo/sandbox/build-support/libraries/system/1/groovy/gbuild/system/util/BastardChildReaper.groovy
  (with props)

Added: geronimo/sandbox/build-support/libraries/system/1/groovy/gbuild/system/util/BastardChildReaper.groovy
URL: http://svn.apache.org/viewvc/geronimo/sandbox/build-support/libraries/system/1/groovy/gbuild/system/util/BastardChildReaper.groovy?view=auto&rev=509100
==============================================================================
--- geronimo/sandbox/build-support/libraries/system/1/groovy/gbuild/system/util/BastardChildReaper.groovy
(added)
+++ geronimo/sandbox/build-support/libraries/system/1/groovy/gbuild/system/util/BastardChildReaper.groovy
Sun Feb 18 22:07:29 2007
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+//
+// $Id$
+//
+
+package gbuild.system.util
+
+import gbuild.system.LogSupport
+
+import org.apache.commons.lang.SystemUtils
+
+/**
+ * Helper to clean up bastard children.
+ */
+class BastardChildReaper extends LogSupport
+{
+    private AntBuilder ant = new gbuild.system.util.AntBuilder()
+    
+    /**
+     * The process ID of the current process.
+     */
+    String pid
+    
+    BastardChildReaper() {
+        pid = sh('echo $PPID')
+        
+        log.info "PID: $pid"
+    }
+    
+    private String sh(String script, List args) {
+        assert script
+        
+        def file = File.createTempFile('reaper', '.sh')
+        file.deleteOnExit()
+        file.write("#!/bin/sh\n$script\n")
+        
+        // Ant does not like to replace props, so make a unique one each time
+        def propname = 'reaper.' + UUID.randomUUID()
+        
+        ant.chmod(perm: 'u+x', file: file)
+        ant.exec(executable: file, failonerror: true, outputproperty: propname) {
+            if (args) {
+                args.each {
+                    arg(value: it)
+                }
+            }
+        }
+        
+        file.delete()
+        
+        return ant.antProject.properties[propname]
+    }
+    
+    private String sh(String script) {
+        return sh(script, null)
+    }
+    
+    def ps(String pattern) {
+        log.info "Getting process list, pattern: $pattern"
+        
+        def ps
+        if (SystemUtils.IS_OS_MAC_OSX) {
+            ps = 'ps -wwao user,pid,ppid,command'
+        }
+        else {
+            ps = 'ps -wweo user,pid,ppid,command'
+        }
+        
+        def cl
+        if (pattern) {
+            cl = "$ps | grep $pattern | grep -v grep"
+        }
+        else {
+            cl = ps
+        }
+        cl += ' | grep -v $0' // Exclude the invoking script
+        
+        List raw = sh(cl).tokenize('\n')
+        List header
+        List result = []
+        
+        raw.each {
+            def cols = it.split('\\s+', 4)
+            
+            if (header == null) {
+                header = cols
+            }
+            else {
+                def entry = [:]
+                for (i in 0 .. (header.size() - 1)) {
+                    def key = header[i]
+                    entry[key] = cols[i]
+                }
+                
+                result << entry
+            }
+        }
+        
+        return result
+    }
+    
+    def ps() {
+        return ps(null)
+    }
+    
+    def children(procs, pid) {
+        assert procs
+        assert pid
+        
+        def list = []
+        
+        procs.each {
+            if (it.PPID == pid) {
+                list << it
+                
+                def l = children(procs, it.PID)
+                if (l) {
+                    list.addAll(l)
+                }
+            }
+        }
+        
+        return list
+    }
+    
+    def kill(pid, boolean force) {
+        log.info "Killing $pid" + (force ? '; forcfully' : '')
+        
+        ant.exec(executable: 'kill', failonerror: false) {
+            if (force) {
+                arg(value: '-9')
+            }
+            arg(value: "$pid")
+        }
+    }
+    
+    def kill(pid) {
+        return kill(pid, false)
+    }
+    
+    def debugSpawn(String script) {
+        assert script
+        
+        def file = File.createTempFile('reaper', '.sh')
+        file.deleteOnExit()
+        file.write("#!/bin/sh\n$script\n")
+        
+        ant.chmod(perm: 'u+x', file: file)
+        ant.exec(executable: file, failonerror: false)
+        
+        file.delete()
+    }
+    
+    def reap() {
+        log.info 'Reaping bastard children'
+        
+        /*
+        def t1 = new Thread({ debugSpawn('(/bin/sleep 10 & (/bin/sleep 10 &)); sleep
10') })
+        t1.start()
+        
+        def t2 = new Thread({ debugSpawn('(/bin/sleep 10 & (/bin/sleep 10 &)); sleep
10') })
+        t2.start()
+        */
+        
+        def bastards = children(ps(), pid)
+        
+        if (bastards) {
+            log.warn 'Found bastards:'
+            bastards.each {
+                log.warn "    $it"
+            }
+            
+            // Kill them all
+            bastards.each {
+                kill(it.PID)
+            }
+            
+            // Wait a few, then look again
+            Thread.sleep(10 * 1000)
+            bastards = children(ps(), pid)
+            
+            if (bastards) {
+                log.warn 'Found evil bastards:'
+                bastards.each {
+                    log.warn "    $it"
+                }
+                
+                // Kill them all with force
+                bastards.each {
+                    kill(it.PID, true)
+                }
+                
+                // Wait a few, then look again
+                Thread.sleep(10 * 1000)
+                bastards = children(ps(), pid)
+                
+                if (bastards) {
+                    log.error 'Found unkillable evil bastards:'
+                    bastards.each {
+                        log.error "    $it"
+                    }
+                }
+            }
+        }
+        else {
+            log.info 'No bastards detected'
+        }
+        
+        /*
+        println "Waiting"
+        
+        t1.join()
+        t2.join()
+        
+        println "Done"
+        */
+    }
+}
+

Propchange: geronimo/sandbox/build-support/libraries/system/1/groovy/gbuild/system/util/BastardChildReaper.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/build-support/libraries/system/1/groovy/gbuild/system/util/BastardChildReaper.groovy
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/sandbox/build-support/libraries/system/1/groovy/gbuild/system/util/BastardChildReaper.groovy
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message