def killProcess(pid): """ Kills the process with the supplied PID, returning a deferred that fires when it's no longer running. The return value is C{True} if the process was alive and had to be killed, C{False} if it was already dead. """ def isDead(): try: status = os.waitpid(pid, os.WNOHANG)[1] except: return True return status != 0 def triedTerm(OK): if not OK: os.kill(pid, signal.SIGKILL) return iteration.Delay().untilEvent( isDead).addCallback(lambda _: True) return True if isDead(): return defer.succeed(False) os.kill(pid, signal.SIGTERM) return iteration.Delay(timeout=5.0).untilEvent( isDead).addCallback(triedTerm)
def deferUntilFewer(self, N, timeout=None): """ Returns a C{Deferred} that fires with C{True} when there are fewer than I{N} tracked deferreds pending. The tracked deferreds do not get bogged down by the callback chain for the returned one. If not enough of the tracked deferreds ever fire and a I{timeout} specified in seconds expires, the returned deferred will fire with C{False}. Calling L{quitWaiting} will make it fire almost immediately, with C{True}. You can add deferreds with calls to L{put} while waiting for this method to finish. That will just add to the number of tracked deferreds pending. See the U{source<http://edsuom.com/ade/ade.population.py>} for the U{ade<http://edsuom.com/ade.html>} package's C{Population} object to see a simple example of this in action. Here's the pertinent code:: @defer.inlineCallbacks def populate(): k = 0 while running(): i = getIndividual() if blank: i.SSE = np.inf addIndividual(i) continue k += 1 d = i.evaluate() d.addCallback(evaluated, d) d.addErrback(oops) dt.put(d) yield dt.deferUntilFewer(self.N_maxParallel) if k >= self.Np: break yield dt.deferToAll() The C{Deferred} that gets yielded while the loop is running fires immediately if there are fewer evaluations going on at once than the limit. Otherwise, it fires when enough evaluations finish to put things below the limit. """ def fewEnoughPending(): return self.dCount is None or self.dCount < N return iteration.Delay( interval=self.interval, backoff=self.backoff, timeout=timeout).untilEvent(fewEnoughPending)
def deferToAll(self, timeout=None): """ Returns a C{Deferred} that tracks all active deferreds that haven't yet fired. When all the tracked deferreds fire, the returned deferred fires, too, with C{True}. The tracked deferreds do not get bogged down by the callback chain for the Deferred returned by this method. If the tracked deferreds never fire and a specified I{timeout} expires, the returned deferred will fire with C{False}. Calling L{quitWaiting} will make it fire almost immediately. """ return iteration.Delay( interval=self.interval, backoff=self.backoff, timeout=timeout).untilEvent(self.notWaiting)
def deferToAny(self, timeout=None): """ Returns a C{Deferred} that fires with C{True} when B{any} of the active deferreds fire. The tracked deferreds do not get bogged down by the callback chain for the returned one. If some of them never fire and a I{timeout} specified in seconds expires, the returned deferred will fire with C{False}. Calling L{quitWaiting} will make it fire almost immediately, with C{True}. B{Caution:} Don't add any deferreds with calls to L{put} while waiting for this method to finish, because it will mess up the count. You will have to wait for one more deferred to fire for each new one you add before the returned deferred fires. """ def oneFired(dCount): return self.dCount is None or self.dCount < dCount dCount = self.dCount # Local dCount has been frozen at my current dCount value return iteration.Delay( interval=self.interval, backoff=self.backoff, timeout=timeout).untilEvent(oneFired, dCount)
def setUp(self): self.do = iteration.Delay() self.event = False
def triedTerm(OK): if not OK: os.kill(pid, signal.SIGKILL) return iteration.Delay().untilEvent( isDead).addCallback(lambda _: True) return True