Merge ~cjwatson/launchpad:librarian-gc-log-delete-failures into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: f88ec60e1d0f4a89ce6be88c5300f35cfa515f74
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:librarian-gc-log-delete-failures
Merge into: launchpad:master
Diff against target: 78 lines (+33/-5)
2 files modified
lib/lp/services/librarianserver/librariangc.py (+9/-5)
lib/lp/services/librarianserver/tests/test_gc.py (+24/-0)
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+414421@code.launchpad.net

Commit message

Make librarian GC log delete failures rather than crashing

Description of the change

librarian-gc has been crashing on every run since at least the start of 2022. A debug run showed that most of the deletions it was attempting from Swift were succeeding, but occasionally one timed out. Since future runs will retry the deletion, it makes sense to log such events rather than crashing.

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) wrote :

Nice fix with good comments in unit test!

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/librarianserver/librariangc.py b/lib/lp/services/librarianserver/librariangc.py
2index aa3429f..26b0462 100644
3--- a/lib/lp/services/librarianserver/librariangc.py
4+++ b/lib/lp/services/librarianserver/librariangc.py
5@@ -553,7 +553,9 @@ class UnreferencedContentPruner:
6 'Swift {}'.format(connection_pool.os_auth_url))
7 except swiftclient.ClientException as x:
8 if x.http_status != 404:
9- raise
10+ log.exception(
11+ "Failed to delete (%s, %s) from Swift (%s)",
12+ container, name, connection_pool.os_auth_url)
13
14 if removed:
15 log.debug3(
16@@ -868,12 +870,14 @@ def delete_unwanted_swift_files(con):
17 with swift.connection(connection_pool) as swift_connection:
18 try:
19 swift_connection.delete_object(container, name)
20+ log.debug3(
21+ 'Deleted (%s, %s) from Swift (%s)',
22+ container, name, connection_pool.os_auth_url)
23 except swiftclient.ClientException as e:
24 if e.http_status != 404:
25- raise
26- log.debug3(
27- 'Deleted (%s, %s) from Swift (%s)',
28- container, name, connection_pool.os_auth_url)
29+ log.exception(
30+ "Failed to delete (%s, %s) from Swift (%s)",
31+ container, name, connection_pool.os_auth_url)
32 removed_count += 1
33
34 if next_wanted_content_id == content_id:
35diff --git a/lib/lp/services/librarianserver/tests/test_gc.py b/lib/lp/services/librarianserver/tests/test_gc.py
36index 716bfa3..7e1eedb 100644
37--- a/lib/lp/services/librarianserver/tests/test_gc.py
38+++ b/lib/lp/services/librarianserver/tests/test_gc.py
39@@ -27,8 +27,10 @@ from six.moves.urllib.parse import urljoin
40 from storm.store import Store
41 from swiftclient import client as swiftclient
42 from testtools.matchers import (
43+ AnyMatch,
44 Equals,
45 MatchesListwise,
46+ MatchesRegex,
47 )
48 import transaction
49
50@@ -759,6 +761,28 @@ class TestSwiftLibrarianGarbageCollection(
51 if x.http_status != 404:
52 raise
53
54+ def test_DeleteUnreferencedContent_handles_timeout(self):
55+ # If delete_unreferenced_content times out trying to delete a file
56+ # from Swift, it logs an error and moves on.
57+
58+ # Merge the duplicates. This creates an
59+ # unreferenced LibraryFileContent.
60+ librariangc.merge_duplicates(self.con)
61+
62+ # Force a timeout from the Swift fixture.
63+ self.pushConfig(
64+ 'librarian_server', os_username='timeout', swift_timeout=0.1)
65+ swift.reconfigure_connection_pools()
66+
67+ # Delete unreferenced content.
68+ librariangc.delete_unreferenced_content(self.con)
69+
70+ # We logged an error message.
71+ self.assertThat(
72+ librariangc.log.getLogBuffer().splitlines(),
73+ AnyMatch(
74+ MatchesRegex(r'^ERROR Failed to delete .* from Swift .*')))
75+
76 def test_delete_unwanted_files_handles_segments(self):
77 # Large files are handled by Swift as multiple segments joined
78 # by a manifest. GC treats the segments like the original file.

Subscribers

People subscribed via source and target branches

to status/vote changes: