Merge lp:~canonical-ca-hackers/ubuntu-webcatalog/fix-scroll-backwards-error into lp:ubuntu-webcatalog

Proposed by Łukasz Czyżykowski
Status: Merged
Approved by: Anthony Lenton
Approved revision: 174
Merged at revision: 176
Proposed branch: lp:~canonical-ca-hackers/ubuntu-webcatalog/fix-scroll-backwards-error
Merge into: lp:ubuntu-webcatalog
Diff against target: 87 lines (+20/-9)
3 files modified
src/webcatalog/management/commands/cleanup.py (+4/-3)
src/webcatalog/tasks.py (+0/-1)
src/webcatalog/tests/test_commands.py (+16/-5)
To merge this branch: bzr merge lp:~canonical-ca-hackers/ubuntu-webcatalog/fix-scroll-backwards-error
Reviewer Review Type Date Requested Status
Anthony Lenton (community) Approve
Review via email: mp+123764@code.launchpad.net

Commit message

Fix 'cursor can only scan forward' error on cleanup tasks.

Description of the change

Overview
========
This branch fixes error with cleanup tasks.

Details
=======
If the remove code would run longer than specified (or default) batch_time the calculation of batch_size would turn it to 0 or -1, which supplied to SQL FETCH would result in an error.

The simplest fix is to just set batch_size to 1 in that case. Documentation of PostgreSQL states that in the event that the cursor was exhausted it will just return 0 rows and not error.

To post a comment you must log in.
Revision history for this message
Anthony Lenton (elachuni) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/webcatalog/management/commands/cleanup.py'
2--- src/webcatalog/management/commands/cleanup.py 2012-07-02 13:51:23 +0000
3+++ src/webcatalog/management/commands/cleanup.py 2012-09-11 14:43:24 +0000
4@@ -131,7 +131,7 @@
5 "Supported tables are: %s" % (table, CLEANERS.keys()))
6 raise CommandError(msg)
7 cleaner = cleaner_cls(self)
8- cur = connection.cursor()
9+ cursor = connection.cursor()
10
11 removed = -1
12 total_removed = 0
13@@ -142,13 +142,14 @@
14 # We don't want to hold the cursor open too long to allow
15 # vacuum to reclaim rows. 1 hour default before it is reopened.
16 if time.time() - cursor_opened_time > cursor_secs:
17- cleaner.declare_expired_keys_cursor(cur)
18+ cleaner.declare_expired_keys_cursor(cursor)
19 cursor_opened_time = time.time()
20
21 # Remove a batch of session rows.
22 batch_start = time.time()
23- removed = cleaner.remove_batch(cur, batch_size)
24+ removed = cleaner.remove_batch(cursor, batch_size)
25 actual_batch_time = time.time() - batch_start
26+
27 total_removed += removed
28 message = "Removed %d rows (%d total removed). Batch size %d\n"
29 self.output(message % (removed, total_removed, batch_size), 1)
30
31=== modified file 'src/webcatalog/tasks.py'
32--- src/webcatalog/tasks.py 2012-06-29 19:51:06 +0000
33+++ src/webcatalog/tasks.py 2012-09-11 14:43:24 +0000
34@@ -1,7 +1,6 @@
35 from time import sleep
36
37 from celery.task import task
38-from django.conf import settings
39 from django.core.management import call_command
40
41
42
43=== modified file 'src/webcatalog/tests/test_commands.py'
44--- src/webcatalog/tests/test_commands.py 2012-08-29 21:46:54 +0000
45+++ src/webcatalog/tests/test_commands.py 2012-09-11 14:43:24 +0000
46@@ -765,7 +765,7 @@
47 # relevant stats.
48 onion = self.factory.make_distroseries(code_name='onion')
49 orig_timestamp = datetime.utcnow() - timedelta(2)
50- import_record = ReviewStatsImport.objects.create(
51+ ReviewStatsImport.objects.create(
52 distroseries=onion, last_import=orig_timestamp)
53
54 call_command('import_ratings_stats', 'onion')
55@@ -1078,10 +1078,7 @@
56
57 @skipUnless(connection.vendor == 'postgresql', "Requires postgresql")
58 def test_cleanup_sessions(self):
59- now = datetime.now()
60- for i in range(8):
61- expire_date = now + timedelta(seconds=5000 * (4 - i))
62- self.factory.make_session(expire_date=expire_date)
63+ self.create_django_sessions()
64 self.assertEqual(8, Session.objects.count())
65
66 call_command('cleanup', 'django_session')
67@@ -1089,6 +1086,20 @@
68 self.assertEqual(4, Session.objects.count())
69 self.check_expected_output()
70
71+ def create_django_sessions(self):
72+ now = datetime.now()
73+ for i in range(8):
74+ expire_date = now + timedelta(seconds=5000 * (4 - i))
75+ self.factory.make_session(expire_date=expire_date)
76+
77+ @skipUnless(connection.vendor == 'postgresql', "Requires postgresql")
78+ def test_cleanup_session_when_it_takes_too_long(self):
79+ self.create_django_sessions()
80+
81+ call_command('cleanup', 'django_session', batch_secs=0)
82+
83+ self.assertEqual(0, Session.objects.count())
84+
85
86 class ImportAllAppInstallDataTestCase(TestCaseWithFactory):
87 @patch('sys.stdout')

Subscribers

People subscribed via source and target branches