Merge lp:~allenap/launchpad/oneiric-librarian-bug-871596 into lp:launchpad

Proposed by Gavin Panella
Status: Rejected
Rejected by: Gavin Panella
Proposed branch: lp:~allenap/launchpad/oneiric-librarian-bug-871596
Merge into: lp:launchpad
Diff against target: 56 lines (+18/-8)
1 file modified
lib/lp/services/database/__init__.py (+18/-8)
To merge this branch: bzr merge lp:~allenap/launchpad/oneiric-librarian-bug-871596
Reviewer Review Type Date Requested Status
Stuart Bishop (community) Disapprove
Launchpad code reviewers Pending
Review via email: mp+79175@code.launchpad.net

Description of the change

It seems that disconnection errors behave slightly differently on Oneiric... possibly. This branch intercepts pgcode 57P01 - admin_shutdown - and allows transactions to be retried instead of just breaking at the first opportunity. Doing this lets the example test command given in the bug to complete without failure.

To post a comment you must log in.
Revision history for this message
Stuart Bishop (stub) wrote :

Rather than fix this in every system, we should just fix it once in Storm. Storm catches the PostgreSQL exceptions, puts its stores in a state so they will attempt to reconnect, and raises DisconnectionError. In particular, I don't think the proposed patch works as the Storm store is being left in an inconsistent state (the next request will likely fail, and the subsequent one might reconnect).

I think this might also be the issue Garry saw with making the appserver return 503 errors when the database was unavailable.

review: Disapprove

Unmerged revisions

14139. By Gavin Panella

Use pgcode instead of string matching.

14138. By Gavin Panella

Treat unexpected disconnections from the database as a possible transient error.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/services/database/__init__.py'
--- lib/lp/services/database/__init__.py 2010-09-24 15:21:05 +0000
+++ lib/lp/services/database/__init__.py 2011-10-12 20:06:13 +0000
@@ -1,4 +1,4 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the1# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""The lp.services.database package."""4"""The lp.services.database package."""
@@ -9,14 +9,16 @@
9 'write_transaction',9 'write_transaction',
10 ]10 ]
1111
12from psycopg2 import OperationalError
12from psycopg2.extensions import TransactionRollbackError13from psycopg2.extensions import TransactionRollbackError
13from storm.exceptions import DisconnectionError, IntegrityError14from storm.exceptions import (
15 DisconnectionError,
16 IntegrityError,
17 )
14import transaction18import transaction
15from twisted.python.util import mergeFunctionMetadata19from twisted.python.util import mergeFunctionMetadata
1620
17from canonical.database.sqlbase import (21from canonical.database.sqlbase import reset_store
18 reset_store,
19 )
2022
2123
22RETRY_ATTEMPTS = 324RETRY_ATTEMPTS = 3
@@ -35,9 +37,18 @@
35 try:37 try:
36 return func(*args, **kwargs)38 return func(*args, **kwargs)
37 except (DisconnectionError, IntegrityError,39 except (DisconnectionError, IntegrityError,
38 TransactionRollbackError), exc:40 TransactionRollbackError):
39 if attempt >= RETRY_ATTEMPTS:41 if attempt >= RETRY_ATTEMPTS:
40 raise # tried too many times42 raise # tried too many times
43 except OperationalError, error:
44 # 57P01 is admin_shutdown:
45 # FATAL: terminating connection due to administrator command
46 # SSL connection has been closed unexpectedly
47 if error.pgcode == "57P01":
48 if attempt >= RETRY_ATTEMPTS:
49 raise # tried too many times
50 else:
51 raise
41 return mergeFunctionMetadata(func, retry_transaction_decorator)52 return mergeFunctionMetadata(func, retry_transaction_decorator)
4253
4354
@@ -77,4 +88,3 @@
77 return ret88 return ret
78 return retry_transaction(mergeFunctionMetadata(89 return retry_transaction(mergeFunctionMetadata(
79 func, write_transaction_decorator))90 func, write_transaction_decorator))
80