Commits

Tres Seaver  committed ba1baea

[svn r832] Added ``eager`` and ``not-eager`` options to httpok.

o If ``not-eager`` is set, and no process being monitored is in the
RUNNING state, skip the URL check / mail message.

  • Participants
  • Parent commits 451b455

Comments (0)

Files changed (3)

File trunk/CHANGES.txt

-0.3
+superlance Changelog
+====================
 
-  Add ``gcore`` and ``coredir`` options to httpok.
+0.4 (unreleased)
+----------------
 
-0.2
+- Added ``eager`` and ``not-eager`` options to httpok.  If ``not-eager``
+  is set, and no process being monitored is in the RUNNING state, skip
+  the URL check / mail message.
 
-  Add crashmail script.
+0.3 (2008-12-10)
+----------------
 
-0.1
+- Added ``gcore`` and ``coredir`` options to httpok.
 
-  Initial release
+0.2 (2008-11-21)
+----------------
+
+- Added crashmail script.
+
+0.1 (2008-09-18)
+----------------
+
+- Initial release

File trunk/superlance/httpok.py

       URL.  If this status code is not the status code provided by the
       response, httpok will attempt to restart processes in the
       RUNNING state specified by -p or -a.  This defaults to the
-      string"200".
+      string, "200".
 
 -b -- specify a string which should be present in the body resulting
       from the GET request.  If this string is not present in the
       address when httpok attempts to restart processes.  If no email
       address is specified, email will not be sent.
 
+-e -- "eager":  check URL / emit mail even if no process we are monitoring
+      is in the RUNNING state.  Enabled by default.
+
+-E -- not "eager":  do not check URL / emit mail if no process we are
+      monitoring is in the RUNNING state.
+
 URL -- The URL to which to issue a GET request.
 
 The -p option may be specified more than once, allowing for
 class HTTPOk:
     connclass = None
     def __init__(self, rpc, programs, any, url, timeout, status, inbody,
-                 email, sendmail, coredir, gcore):
+                 email, sendmail, coredir, gcore, eager):
         self.rpc = rpc
         self.programs = programs
         self.any = any
         self.sendmail = sendmail
         self.coredir = coredir
         self.gcore = gcore
+        self.eager = eager
         self.stdin = sys.stdin
         self.stdout = sys.stdout
         self.stderr = sys.stderr
 
+    def listProcesses(self, state=None):
+        return [x for x in self.rpc.supervisor.getAllProcessInfo()
+                   if x['name'] in self.programs and
+                      (state is None or x['state'] == state)]
+
     def runforever(self, test=False):
         parsed = urlparse.urlsplit(self.url)
         scheme = parsed[0].lower()
 
             act = False
 
+            if not self.eager:
+                specs = self.listProcesses(ProcessStates.RUNNING)
+                if len(specs) == 0:
+                    if test:
+                        break
+                    continue
+
             try:
                 conn.request('GET', path)
                 res = conn.getresponse()
 
 def main(argv=sys.argv):
     import getopt
-    short_args="hp:at:c:b:s:m:g:d:"
+    short_args="hp:at:c:b:s:m:g:d:eE"
     long_args=[
         "help",
         "program=",
         "email=",
         "gcore=",
         "coredir=",
+        "eager",
+        "not-eager",
         ]
     arguments = argv[1:]
     try:
     sendmail = '/usr/sbin/sendmail -t -i'
     gcore = '/usr/bin/gcore -o'
     coredir = None
+    eager = True
     email = None
     timeout = 10
     status = '200'
         if option in ('-d', '--coredir'):
             coredir = value
 
+        if option in ('-e', '--eager'):
+            eager = True
+
+        if option in ('-E', '--not-eager'):
+            eager = False
+
     url = arguments[-1]
 
     try:
         return
 
     prog = HTTPOk(rpc, programs, any, url, timeout, status, inbody, email,
-                  sendmail, coredir, gcore)
+                  sendmail, coredir, gcore, eager)
     prog.runforever()
 
 if __name__ == '__main__':

File trunk/superlance/tests.py

         return self._getTargetClass()(*opts)
 
     def _makeOnePopulated(self, programs, any, response=None, exc=None,
-                          gcore=None, coredir=None):
+                          gcore=None, coredir=None, eager=True):
         if response is None:
             response = DummyResponse()
         rpc = DummyRPCServer()
         gcore = gcore
         coredir = coredir
         prog = self._makeOne(rpc, programs, any, url, timeout, status,
-                             inbody, email, sendmail, coredir, gcore)
+                             inbody, email, sendmail, coredir, gcore, eager)
         prog.stdin = StringIO()
         prog.stdout = StringIO()
         prog.stderr = StringIO()
         prog.connclass = make_connection(response, exc=exc)
         return prog
-        
-    def test_runforever_notatick(self):
+
+    def test_listProcesses_no_programs(self):
+        programs = []
+        any = None
+        prog = self._makeOnePopulated(programs, any)
+        specs = list(prog.listProcesses())
+        self.assertEqual(len(specs), 0)
+
+    def test_listProcesses_w_RUNNING_programs_default_state(self):
+        programs = ['foo']
+        any = None
+        prog = self._makeOnePopulated(programs, any)
+        specs = list(prog.listProcesses())
+        self.assertEqual(len(specs), 1)
+        self.assertEqual(specs[0],
+                         DummySupervisorRPCNamespace.all_process_info[0])
+
+    def test_listProcesses_w_nonRUNNING_programs_default_state(self):
+        programs = ['bar']
+        any = None
+        prog = self._makeOnePopulated(programs, any)
+        specs = list(prog.listProcesses())
+        self.assertEqual(len(specs), 1)
+        self.assertEqual(specs[0],
+                         DummySupervisorRPCNamespace.all_process_info[1])
+
+    def test_listProcesses_w_nonRUNNING_programs_RUNNING_state(self):
+        programs = ['bar']
+        any = None
+        prog = self._makeOnePopulated(programs, any)
+        specs = list(prog.listProcesses(ProcessStates.RUNNING))
+        self.assertEqual(len(specs), 0, (prog.programs, specs))
+
+    def test_runforever_eager_notatick(self):
         programs = {'foo':0, 'bar':0, 'baz_01':0 }
         groups = {}
         any = None
         prog.runforever(test=True)
         self.assertEqual(prog.stderr.getvalue(), '')
 
-    def test_runforever_error_on_request_some(self):
+    def test_runforever_eager_error_on_request_some(self):
         programs = ['foo', 'bar', 'baz_01', 'notexisting']
         any = None
         prog = self._makeOnePopulated(programs, any, exc=True)
         self.assertEqual(mailed[1],
                     'Subject: httpok for http://foo/bar: bad status returned')
 
-    def test_runforever_error_on_request_any(self):
+    def test_runforever_eager_error_on_request_any(self):
         programs = []
         any = True
         prog = self._makeOnePopulated(programs, any, exc=True)
         self.assertEqual(mailed[1],
                     'Subject: httpok for http://foo/bar: bad status returned')
 
-    def test_runforever_error_on_process_stop(self):
+    def test_runforever_eager_error_on_process_stop(self):
         programs = ['FAILED']
         any = False
         prog = self._makeOnePopulated(programs, any, exc=True)
         self.assertEqual(mailed[1],
                     'Subject: httpok for http://foo/bar: bad status returned')
 
-    def test_runforever_error_on_process_start(self):
+    def test_runforever_eager_error_on_process_start(self):
         programs = ['SPAWN_ERROR']
         any = False
         prog = self._makeOnePopulated(programs, any, exc=True)
         self.assertEqual(mailed[1],
                     'Subject: httpok for http://foo/bar: bad status returned')
 
-    def test_runforever_gcore(self):
+    def test_runforever_eager_gcore(self):
         programs = ['foo', 'bar', 'baz_01', 'notexisting']
         any = None
         prog = self._makeOnePopulated(programs, any, exc=True, gcore="true",
         self.assertEqual(mailed[1],
                     'Subject: httpok for http://foo/bar: bad status returned')
 
+    def test_runforever_not_eager_none_running(self):
+        programs = ['bar', 'baz_01']
+        any = None
+        prog = self._makeOnePopulated(programs, any, exc=True, gcore="true",
+                                      coredir="/tmp", eager=False)
+        prog.stdin.write('eventname:TICK len:0\n')
+        prog.stdin.seek(0)
+        prog.runforever(test=True)
+        lines = filter(None, prog.stderr.getvalue().split('\n'))
+        self.assertEqual(len(lines), 0, lines)
+        self.failIf('mailed' in prog.__dict__)
+
 class CrashMailTests(unittest.TestCase):
     def _getTargetClass(self):
         from superlance.crashmail import CrashMail