← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:remove-old-signal-handlers into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:remove-old-signal-handlers into launchpad:master.

Commit message:
Remove old webapp SIGHUP/SIGUSR1/SIGUSR2 handlers

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/405898

These are neither useful nor usable when running under gunicorn (because gunicorn provides similar facilities for the most part, and also installs handlers for these signals itself).
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:remove-old-signal-handlers into launchpad:master.
diff --git a/lib/lp/services/webapp/adapter.py b/lib/lp/services/webapp/adapter.py
index d2d1d86..1994457 100644
--- a/lib/lp/services/webapp/adapter.py
+++ b/lib/lp/services/webapp/adapter.py
@@ -660,9 +660,6 @@ class LaunchpadStatementTracer:
             if print_traceback:
                 print_list(stack)
                 sys.stderr.write("." * 70 + "\n")
-        # store the last executed statement as an attribute on the current
-        # thread
-        threading.current_thread().lp_last_sql_statement = statement
         request_starttime = getattr(_local, 'request_start_time', None)
         if request_starttime is None:
             if print_traceback or self._debug_sql or log_sql is not None:
diff --git a/lib/lp/services/webapp/configure.zcml b/lib/lp/services/webapp/configure.zcml
index edd452c..cb5b6b4 100644
--- a/lib/lp/services/webapp/configure.zcml
+++ b/lib/lp/services/webapp/configure.zcml
@@ -338,18 +338,6 @@
     <!-- Signal handlers -->
     <subscriber
         for="zope.processlifetime.IProcessStarting"
-        handler="lp.services.webapp.sighup.setup_sighup"
-        />
-    <subscriber
-        for="zope.processlifetime.IProcessStarting"
-        handler="lp.services.webapp.sigusr1.setup_sigusr1"
-        />
-    <subscriber
-        for="zope.processlifetime.IProcessStarting"
-        handler="lp.services.webapp.sigusr2.setup_sigusr2"
-        />
-    <subscriber
-        for="zope.processlifetime.IProcessStarting"
         handler="lp.services.webapp.sigdumpmem.setup_sigdumpmem"
         />
 
@@ -359,16 +347,6 @@
         handler="lp.services.webapp.adapter.set_launchpad_default_timeout"
         />
 
-    <subscriber
-        for="zope.traversing.interfaces.IBeforeTraverseEvent"
-        handler="lp.services.webapp.sigusr1.before_traverse"
-        />
-
-    <subscriber
-        for="zope.publisher.interfaces.IEndRequestEvent"
-        handler="lp.services.webapp.sigusr1.end_request"
-        />
-
     <class class="lp.services.webapp.publication.LoginRoot">
       <allow
         attributes="publishTraverse"
diff --git a/lib/lp/services/webapp/sighup.py b/lib/lp/services/webapp/sighup.py
deleted file mode 100644
index 7623bdb..0000000
--- a/lib/lp/services/webapp/sighup.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Signal handler for SIGHUP."""
-
-__metaclass__ = type
-__all__ = []
-
-import logging
-import signal
-
-from lp.services.webapp import haproxy
-
-
-def sighup_handler(signum, frame):
-    """Switch the state of the HAProxy going_down flag."""
-    haproxy.switch_going_down_flag()
-    logging.getLogger('sighup').info(
-        'Received SIGHUP, swiched going_down flag to %s' %
-        haproxy.going_down_flag)
-
-
-def setup_sighup(event):
-    """Configure the SIGHUP handler.  Called at startup."""
-    signal.signal(signal.SIGHUP, sighup_handler)
diff --git a/lib/lp/services/webapp/sigusr1.py b/lib/lp/services/webapp/sigusr1.py
deleted file mode 100644
index 1ef7c80..0000000
--- a/lib/lp/services/webapp/sigusr1.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""A SIGUSR1 handler for the Launchpad Web App.
-
-To aid debugging, we install a handler for the SIGUSR1 signal.  When
-received, a summary of the last request, recent OOPS IDs and last
-executed SQL statement is printed for each thread.
-"""
-
-import logging
-import signal
-import threading
-
-
-def sigusr1_handler(signum, frame):
-    """Log status of running threads in response to SIGUSR1"""
-    message = ['Thread summary:']
-    for thread in threading.enumerate():
-        # if the thread has no lp_last_request attribute, it probably
-        # isn't an appserver thread.
-        if not hasattr(thread, 'lp_last_request'):
-            continue
-        message.append('\t%s' % thread.name)
-        message.append('\t\tLast Request: %s' % thread.lp_last_request)
-        message.append('\t\tMost recent OOPS IDs: %s' %
-                       ', '.join(getattr(thread, 'lp_last_oops', [])))
-        message.append('\t\tLast SQL statement: %s' %
-                       getattr(thread, 'lp_last_sql_statement', None))
-    logging.getLogger('sigusr1').info('\n'.join(message))
-
-
-def setup_sigusr1(event):
-    """Configure the SIGUSR1 handler.  Called at startup."""
-    signal.signal(signal.SIGUSR1, sigusr1_handler)
-
-
-def before_traverse(event):
-    """Record the request URL (provided that the request has a URL)"""
-    request = event.request
-    threading.current_thread().lp_last_request = str(
-        getattr(request, 'URL', ''))
-
-
-def end_request(event):
-    """Record the OOPS ID in the thread, if one occurred."""
-    request = event.request
-    if request.oopsid is not None:
-        thread = threading.current_thread()
-        last_oops_ids = getattr(thread, 'lp_last_oops', [])
-        # make sure the OOPS ID list has at most 5 elements
-        thread.lp_last_oops = last_oops_ids[-4:] + [request.oopsid]
diff --git a/lib/lp/services/webapp/sigusr2.py b/lib/lp/services/webapp/sigusr2.py
deleted file mode 100644
index 1e6aa6c..0000000
--- a/lib/lp/services/webapp/sigusr2.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""A SIGUSR2 handler for the Launchpad Web App.
-
-Sending a SIGUSR2 signal to Launchpad will cause logfiles to be
-reopened, allowing a tool like logrotate to rotate them.
-"""
-
-__metaclass__ = type
-__all__ = ['setup_sigusr2']
-
-import signal
-
-from ZConfig.components.logger.loghandler import reopenFiles
-
-
-def sigusr2_handler(signum, frame):
-    "Rotate logfiles in response to SIGUSR2."""
-    reopenFiles()
-
-
-def setup_sigusr2(event):
-    """Configure the SIGUSR2 handler. Called at startup."""
-    signal.signal(signal.SIGUSR2, sigusr2_handler)
diff --git a/lib/lp/services/webapp/tests/sigusr2.py b/lib/lp/services/webapp/tests/sigusr2.py
deleted file mode 100644
index 5359ec6..0000000
--- a/lib/lp/services/webapp/tests/sigusr2.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Helper for test_sigusr2.py."""
-
-import logging
-import os.path
-import signal
-import sys
-
-from ZConfig.components.logger.loghandler import FileHandler
-
-from lp.services.webapp.sigusr2 import setup_sigusr2
-
-
-def notify(step):
-    # Quick way of communicating back to the test suite for synchronization.
-    open(os.path.join(os.path.dirname(sys.argv[1]), step), 'w').write('')
-
-
-_counter = 1
-
-
-def sigusr1_handler(signum, frame):
-    """Emit a message"""
-    global _counter
-    logging.getLogger('').error('Message %d' % _counter)
-    notify('emit_%d' % _counter)
-    _counter += 1
-
-
-_installed_handler = None
-
-
-def sigusr2_handler(signum, frame):
-    _installed_handler(signum, frame)
-    notify('sigusr2')
-
-
-if __name__ == '__main__':
-    logging.getLogger('').addHandler(FileHandler(sys.argv[1]))
-    signal.signal(signal.SIGUSR1, sigusr1_handler)
-
-    # Install the SIGUSR2 handler, and wrap it so there are notifications
-    # when it is invoked.
-    setup_sigusr2(None)
-    _installed_handler = signal.signal(signal.SIGUSR2, sigusr2_handler)
-
-    notify('ready')
-    while True:
-        signal.pause()
diff --git a/lib/lp/services/webapp/tests/test_sighup.py b/lib/lp/services/webapp/tests/test_sighup.py
deleted file mode 100644
index 1c07e3b..0000000
--- a/lib/lp/services/webapp/tests/test_sighup.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test the SIGHUP signal handler."""
-
-__metaclass__ = type
-
-import os
-import signal
-
-from lp.services.webapp import (
-    haproxy,
-    sighup,
-    )
-from lp.testing import TestCase
-from lp.testing.layers import FunctionalLayer
-
-
-class SIGHUPTestCase(TestCase):
-    layer = FunctionalLayer
-
-    def setUp(self):
-        TestCase.setUp(self)
-        self.original_handler = signal.getsignal(signal.SIGHUP)
-        self.addCleanup(signal.signal, signal.SIGHUP, self.original_handler)
-        sighup.setup_sighup(None)
-
-        self.original_flag = haproxy.going_down_flag
-        self.addCleanup(haproxy.set_going_down_flag, self.original_flag)
-
-    def test_sighup(self):
-        # Sending SIGHUP should switch the PID
-        os.kill(os.getpid(), signal.SIGHUP)
-        self.assertEqual(not self.original_flag, haproxy.going_down_flag)
-
-        # Sending again should switch again.
-        os.kill(os.getpid(), signal.SIGHUP)
-        self.assertEqual(self.original_flag, haproxy.going_down_flag)
diff --git a/lib/lp/services/webapp/tests/test_sigusr2.py b/lib/lp/services/webapp/tests/test_sigusr2.py
deleted file mode 100644
index 87dfd4e..0000000
--- a/lib/lp/services/webapp/tests/test_sigusr2.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test the SIGUSR2 signal handler."""
-
-__metaclass__ = type
-__all__ = []
-
-import os.path
-import shutil
-import signal
-import subprocess
-import sys
-import tempfile
-import time
-import unittest
-
-
-class SIGUSR2TestCase(unittest.TestCase):
-    def setUp(self):
-        self.logdir = tempfile.mkdtemp()
-
-    def tearDown(self):
-        shutil.rmtree(self.logdir)
-
-    def test_sigusr2(self):
-        main_log = os.path.join(self.logdir, 'main')
-        cycled_log = os.path.join(self.logdir, 'cycled')
-
-        helper_cmd = [
-            sys.executable,
-            os.path.join(os.path.dirname(__file__), 'sigusr2.py'),
-            main_log]
-        proc = subprocess.Popen(
-            helper_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-        try:
-            # Wait until things have started up.
-            self.sync('ready')
-
-            # Make the helper emit a log message.
-            os.kill(proc.pid, signal.SIGUSR1)
-            self.sync('emit_1')
-
-            # Move the log file under the helper's feed.
-            os.rename(main_log, cycled_log)
-
-            # Emit another log message. This will go to cycled_log
-            # as the helper hasn't reopened its logs yet.
-            os.kill(proc.pid, signal.SIGUSR1)
-            self.sync('emit_2')
-
-            # Invoke the sigusr2 handler in the helper. This reopens
-            # the logs, so the helper will start logging to main_log
-            # again.
-            os.kill(proc.pid, signal.SIGUSR2)
-            self.sync('sigusr2')
-
-            # Make the helper emit a log message.
-            os.kill(proc.pid, signal.SIGUSR1)
-            self.sync('emit_3')
-        finally:
-            os.kill(proc.pid, signal.SIGKILL)
-
-        # Confirm content in the main log and the cycled log are what we
-        # expect.
-        with open(cycled_log) as f:
-            self.assertEqual(f.read(), 'Message 1\nMessage 2\n')
-        with open(main_log) as f:
-            self.assertEqual(f.read(), 'Message 3\n')
-
-    def sync(self, step):
-        retries = 200
-        event_filename = os.path.join(self.logdir, step)
-        for i in range(retries):
-            if os.path.exists(event_filename):
-                os.unlink(event_filename)
-                return
-            time.sleep(0.3)
-        self.fail("sync step %s didn't happen after %d retries." % (
-            step, retries))