Merge ~cjwatson/launchpad:tracer-action-leak into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: cfc08c8c41f53c42d96f84432b89c622a673bfeb
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:tracer-action-leak
Merge into: launchpad:master
Diff against target: 48 lines (+22/-0)
2 files modified
lib/lp/services/webapp/adapter.py (+2/-0)
lib/lp/services/webapp/tests/test_statementtracer.py (+20/-0)
Reviewer Review Type Date Requested Status
Cristian Gonzalez (community) Approve
Review via email: mp+403272@code.launchpad.net

Commit message

Clear connection._lp_statement_action after tracing it

Description of the change

Since database connections are typically cached, leaving TimedAction references lying around on them makes life more difficult for the cyclic garbage collector and makes it harder to track down memory leaks.

To post a comment you must log in.
Revision history for this message
Cristian Gonzalez (cristiangsp) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/services/webapp/adapter.py b/lib/lp/services/webapp/adapter.py
2index 637ad17..a707e11 100644
3--- a/lib/lp/services/webapp/adapter.py
4+++ b/lib/lp/services/webapp/adapter.py
5@@ -637,6 +637,7 @@ class LaunchpadTimeoutTracer(PostgresTimeoutTracer):
6 # action may be None if the tracer was installed after
7 # the statement was submitted.
8 action.finish()
9+ connection._lp_statement_action = None
10 info = sys.exc_info()
11 transaction.doom()
12 try:
13@@ -732,6 +733,7 @@ class LaunchpadStatementTracer:
14 # statement was submitted or if the timeline tracer is not
15 # installed.
16 action.finish()
17+ connection._lp_statement_action = None
18 log_sql = getattr(_local, 'sql_logging', None)
19 if log_sql is not None or self._debug_sql or self._debug_sql_extra:
20 data = None
21diff --git a/lib/lp/services/webapp/tests/test_statementtracer.py b/lib/lp/services/webapp/tests/test_statementtracer.py
22index bc5ddef..4ba6b53 100644
23--- a/lib/lp/services/webapp/tests/test_statementtracer.py
24+++ b/lib/lp/services/webapp/tests/test_statementtracer.py
25@@ -368,3 +368,23 @@ class TestLoggingWithinRequest(TestCaseWithFactory):
26 tracer.connection_raw_execute_success(
27 self.connection, None, 'SELECT * FROM three', ())
28 self.assertEqual(['SELECT * FROM three'], logger.statements)
29+
30+ def test_clears_timeline_action_reference(self):
31+ # The tracer doesn't leave TimedAction references lying around in
32+ # the connection.
33+ tracer = da.LaunchpadStatementTracer()
34+ with person_logged_in(self.person):
35+ with StormStatementRecorder():
36+ tracer.connection_raw_execute(
37+ self.connection, None, 'SELECT * FROM one', ())
38+ self.assertIsNotNone(self.connection._lp_statement_action)
39+ tracer.connection_raw_execute_success(
40+ self.connection, None, 'SELECT * FROM one', ())
41+ self.assertIsNone(self.connection._lp_statement_action)
42+ tracer.connection_raw_execute(
43+ self.connection, None, 'SELECT * FROM one', ())
44+ self.assertIsNotNone(self.connection._lp_statement_action)
45+ tracer.connection_raw_execute_error(
46+ self.connection, None, 'SELECT * FROM one', (),
47+ Exception())
48+ self.assertIsNone(self.connection._lp_statement_action)

Subscribers

People subscribed via source and target branches

to status/vote changes: