Merge lp:~salgado/launchpad/meliae-librarian into lp:launchpad

Proposed by Guilherme Salgado
Status: Merged
Approved by: Gary Poster
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~salgado/launchpad/meliae-librarian
Merge into: lp:launchpad
Diff against target: 94 lines (+54/-0)
3 files modified
daemons/librarian.tac (+11/-0)
lib/canonical/librarian/interfaces.py (+6/-0)
lib/canonical/librarian/tests/test_sigdumpmem.py (+37/-0)
To merge this branch: bzr merge lp:~salgado/launchpad/meliae-librarian
Reviewer Review Type Date Requested Status
Gary Poster (community) Approve
Review via email: mp+23771@code.launchpad.net

Description of the change

Make the librarian dump its memory (using meliae) upon a 'kill -44'

This is to help debug bug 556245.

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/canonical/librarian/interfaces.py
  lib/canonical/librarian/tests/test_sigdumpmem.py
  daemons/librarian.tac

== Pylint notices ==

lib/canonical/librarian/tests/test_sigdumpmem.py
    11: [F0401] Unable to import 'canonical.librarian.interfaces'
    12: [F0401] Unable to import 'canonical.librarian.ftests.harness'
    13: [F0401] Unable to import 'canonical.testing.layers'
    14: [F0401] Unable to import 'lp.testing'

To post a comment you must log in.
Revision history for this message
Gary Poster (gary) wrote :

Thank you

Gary

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'daemons/librarian.tac'
2--- daemons/librarian.tac 2009-06-24 20:55:31 +0000
3+++ daemons/librarian.tac 2010-04-20 14:37:25 +0000
4@@ -4,6 +4,10 @@
5 # Twisted Application Configuration file.
6 # Use with "twistd2.4 -y <file.tac>", e.g. "twistd -noy server.tac"
7
8+import signal
9+
10+from meliae import scanner
11+
12 from twisted.application import service, strports
13 from twisted.web import server
14
15@@ -11,6 +15,7 @@
16 from canonical.launchpad.daemons import tachandler
17 from canonical.launchpad.scripts import execute_zcml_for_scripts
18
19+from canonical.librarian.interfaces import DUMP_FILE, SIGDUMPMEM
20 from canonical.librarian.libraryprotocol import FileUploadFactory
21 from canonical.librarian import storage, db
22 from canonical.librarian import web as fatweb
23@@ -64,3 +69,9 @@
24 webPort = config.librarian.restricted_download_port
25 uploadPort = config.librarian.restricted_upload_port
26 setUpListener(uploadPort, webPort, restricted=True)
27+
28+# Setup a signal handler to dump the process' memory upon 'kill -44'.
29+def sigdumpmem_handler(signum, frame):
30+ scanner.dump_all_objects(DUMP_FILE)
31+
32+signal.signal(SIGDUMPMEM, sigdumpmem_handler)
33
34=== modified file 'lib/canonical/librarian/interfaces.py'
35--- lib/canonical/librarian/interfaces.py 2009-06-25 05:30:52 +0000
36+++ lib/canonical/librarian/interfaces.py 2010-04-20 14:37:25 +0000
37@@ -5,9 +5,15 @@
38 # pylint: disable-msg=E0213
39 __metaclass__ = type
40
41+import signal
42+
43 from zope.interface import Interface
44
45
46+SIGDUMPMEM = signal.SIGRTMIN + 10
47+DUMP_FILE = '/tmp/librarian-memory.dump'
48+
49+
50 class LibrarianFailure(Exception):
51 """Base class for failures trying to use the libararian."""
52
53
54=== added file 'lib/canonical/librarian/tests/test_sigdumpmem.py'
55--- lib/canonical/librarian/tests/test_sigdumpmem.py 1970-01-01 00:00:00 +0000
56+++ lib/canonical/librarian/tests/test_sigdumpmem.py 2010-04-20 14:37:25 +0000
57@@ -0,0 +1,37 @@
58+# Copyright 2010 Canonical Ltd. This software is licensed under the
59+# GNU Affero General Public License version 3 (see the file LICENSE).
60+
61+"""Test the SIGDUMPMEM signal handler."""
62+
63+__metaclass__ = type
64+
65+import os
66+import time
67+
68+from canonical.librarian.interfaces import DUMP_FILE, SIGDUMPMEM
69+from canonical.librarian.ftests.harness import TacLibrarianTestSetup
70+from canonical.testing.layers import LibrarianLayer
71+from lp.testing import TestCase
72+
73+
74+class SIGDUMPMEMTestCase(TestCase):
75+ layer = LibrarianLayer
76+
77+ def test_sigdumpmem(self):
78+ # Remove the dump file, if one exists.
79+ if os.path.exists(DUMP_FILE):
80+ os.unlink(DUMP_FILE)
81+ self.assertFalse(os.path.exists(DUMP_FILE))
82+
83+ # We rely on the fact that the librarian was started by the test
84+ # runner here as we use the LibrarianLayer.
85+ pid = int(open(TacLibrarianTestSetup().pidfile).read())
86+
87+ # Send the signal and ensure the dump file is created.
88+ os.kill(pid, SIGDUMPMEM)
89+ timeout = 5
90+ start_time = time.time()
91+ while time.time() < start_time + timeout:
92+ if os.path.exists(DUMP_FILE):
93+ break
94+ self.assertTrue(os.path.exists(DUMP_FILE))