Merge lp:~therp-nl/openobject-server/ronald@therp.nl_fix_orm_lp1009014-6.1 into lp:openobject-server/6.1

Proposed by Ronald Portier (Therp)
Status: Needs review
Proposed branch: lp:~therp-nl/openobject-server/ronald@therp.nl_fix_orm_lp1009014-6.1
Merge into: lp:openobject-server/6.1
Diff against target: 101 lines (+29/-39)
1 file modified
openerp/osv/orm.py (+29/-39)
To merge this branch: bzr merge lp:~therp-nl/openobject-server/ronald@therp.nl_fix_orm_lp1009014-6.1
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+108945@code.launchpad.net

Description of the change

This branches fixes bug #1009014

- It properly computes when vacuum cleaning should be done

- It has a safeguard against deleting recent records, that have a huge chance of still being in use

- It removes the obsolete, unneeded and non-functional code to trigger cleaning on max number of records

To post a comment you must log in.

Unmerged revisions

4197. By Ronald Portier (Therp)

[FIX] Updated vacuum cleaning of transient models;
- corrected check to prevent too frequent execution
- removed buggy code testing for max count
- consolidated everything, except retrieving configuration, in the one method _transient_vacuum
- made all code PEP8 compliant

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/osv/orm.py'
2--- openerp/osv/orm.py 2012-06-04 11:45:36 +0000
3+++ openerp/osv/orm.py 2012-06-06 13:50:22 +0000
4@@ -673,10 +673,7 @@
5 _group_by_full = {}
6
7 # Transience
8- _transient = False # True in a TransientModel
9- _transient_max_count = None
10- _transient_max_hours = None
11- _transient_check_time = 20
12+ _transient = False # True in a TransientModel
13
14 # structure:
15 # { 'parent_model': 'm2o_field', ... }
16@@ -1057,10 +1054,11 @@
17 # Transience
18 if self.is_transient():
19 self._transient_check_count = 0
20- self._transient_max_count = config.get('osv_memory_count_limit')
21- self._transient_max_hours = config.get('osv_memory_age_limit')
22- assert self._log_access, "TransientModels must have log_access turned on, "\
23- "in order to implement their access rights policy"
24+ self._transient_max_count = config.get('osv_memory_count_limit', 0)
25+ self._transient_max_hours = config.get('osv_memory_age_limit', 0)
26+ assert self._log_access, (
27+ "TransientModels must have log_access turned on, "
28+ "in order to implement their access rights policy")
29
30 def __export_row(self, cr, uid, row, fields, context=None):
31 if context is None:
32@@ -4881,46 +4879,38 @@
33 """
34 return self._transient
35
36- def _transient_clean_rows_older_than(self, cr, seconds):
37- assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name
38- cr.execute("SELECT id FROM " + self._table + " WHERE"
39- " COALESCE(write_date, create_date, (now() at time zone 'UTC'))::timestamp <"
40- " ((now() at time zone 'UTC') - interval %s)", ("%s seconds" % seconds,))
41- ids = [x[0] for x in cr.fetchall()]
42- self.unlink(cr, SUPERUSER_ID, ids)
43-
44- def _transient_clean_old_rows(self, cr, count):
45- assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name
46- cr.execute(
47- "SELECT id, COALESCE(write_date, create_date, (now() at time zone 'UTC'))::timestamp"
48- " AS t FROM " + self._table +
49- " ORDER BY t LIMIT %s", (count,))
50- ids = [x[0] for x in cr.fetchall()]
51- self.unlink(cr, SUPERUSER_ID, ids)
52-
53 def _transient_vacuum(self, cr, uid, force=False):
54 """Clean the transient records.
55
56 This unlinks old records from the transient model tables whenever the
57 "_transient_max_count" or "_max_age" conditions (if any) are reached.
58- Actual cleaning will happen only once every "_transient_check_time" calls.
59+ Actual cleaning will happen only once every "_transient_check_time"
60+ calls.
61 This means this method can be called frequently called (e.g. whenever
62 a new record is created).
63+ 2012-06-06: _transient_max_count not used/implemented for the moment
64 """
65- assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name
66+ assert self._transient, (
67+ "Model %s is not transient, it cannot be vacuumed!" % self._name)
68+ _transient_check_time = 20 # arbitrary limit on vacuum executions
69 self._transient_check_count += 1
70- if (not force) and (self._transient_check_count % self._transient_check_time):
71- self._transient_check_count = 0
72- return True
73-
74- # Age-based expiration
75- if self._transient_max_hours:
76- self._transient_clean_rows_older_than(cr, self._transient_max_hours * 60 * 60)
77-
78- # Count-based expiration
79- if self._transient_max_count:
80- self._transient_clean_old_rows(cr, self._transient_max_count)
81-
82+ if ((not force)
83+ and (self._transient_check_count % _transient_check_time)):
84+ return True # no vacuum cleaning this time
85+ self._transient_check_count = 0
86+ '''For the moment we just use age-based expiration. And we will
87+ never delete records that have been changed / created in the
88+ last 5 minutes. (Arbitrary value, we might make this a configurable
89+ option).'''
90+ seconds = max(self._transient_max_hours * 60 * 60, 600)
91+ now_str = "(now() at time zone 'UTC')"
92+ cr.execute(
93+ "SELECT id FROM " + self._table + " WHERE"
94+ " COALESCE(write_date, create_date, " + now_str + ")::timestamp"
95+ "< (" + now_str + " - interval %s)", ("%s seconds" % seconds,))
96+ ids = [x[0] for x in cr.fetchall()]
97+ if ids:
98+ self.unlink(cr, SUPERUSER_ID, ids)
99 return True
100
101 def resolve_o2m_commands_to_record_dicts(self, cr, uid, field_name, o2m_commands, fields=None, context=None):