Merge lp:~therp-nl/openobject-server/ronald@therp.nl_6.1_lp1009014_new-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_6.1_lp1009014_new-6.1
Merge into: lp:openobject-server/6.1
Diff against target: 78 lines (+31/-18)
1 file modified
openerp/osv/orm.py (+31/-18)
To merge this branch: bzr merge lp:~therp-nl/openobject-server/ronald@therp.nl_6.1_lp1009014_new-6.1
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+131201@code.launchpad.net

Description of the change

Fix vacuum cleaning on transient object.

This is a new proposal taking into account the remarks made by Vo Minh Thu.

To post a comment you must log in.

Unmerged revisions

4290. By Ronald Portier (Therp)

[FIX] Fix vacuum cleaning both for time and count based cleaning,
      adding a safeguard against cleaning recently used rows.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openerp/osv/orm.py'
--- openerp/osv/orm.py 2012-09-24 14:00:07 +0000
+++ openerp/osv/orm.py 2012-10-24 14:59:30 +0000
@@ -674,9 +674,6 @@
674674
675 # Transience675 # Transience
676 _transient = False # True in a TransientModel676 _transient = False # True in a TransientModel
677 _transient_max_count = None
678 _transient_max_hours = None
679 _transient_check_time = 20
680677
681 # structure:678 # structure:
682 # { 'parent_model': 'm2o_field', ... }679 # { 'parent_model': 'm2o_field', ... }
@@ -4889,20 +4886,26 @@
48894886
4890 def _transient_clean_rows_older_than(self, cr, seconds):4887 def _transient_clean_rows_older_than(self, cr, seconds):
4891 assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name4888 assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name
4892 cr.execute("SELECT id FROM " + self._table + " WHERE"4889 '''Never delete rows used in last 5 minutes'''
4893 " COALESCE(write_date, create_date, (now() at time zone 'UTC'))::timestamp <"4890 seconds = max(seconds, 300)
4894 " ((now() at time zone 'UTC') - interval %s)", ("%s seconds" % seconds,))4891 now_str = "(now() at time zone 'UTC')"
4895 ids = [x[0] for x in cr.fetchall()]
4896 self.unlink(cr, SUPERUSER_ID, ids)
4897
4898 def _transient_clean_old_rows(self, cr, count):
4899 assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name
4900 cr.execute(4892 cr.execute(
4901 "SELECT id, COALESCE(write_date, create_date, (now() at time zone 'UTC'))::timestamp"4893 "SELECT id FROM " + self._table + " WHERE"
4902 " AS t FROM " + self._table +4894 " COALESCE(write_date, create_date, " + now_str + ")::timestamp"
4903 " ORDER BY t LIMIT %s", (count,))4895 "< (" + now_str + " - interval %s)", ("%s seconds" % seconds,))
4904 ids = [x[0] for x in cr.fetchall()]4896 ids = [x[0] for x in cr.fetchall()]
4905 self.unlink(cr, SUPERUSER_ID, ids)4897 if ids:
4898 self.unlink(cr, SUPERUSER_ID, ids)
4899
4900 def _transient_clean_old_rows(self, cr, max_count):
4901 # Check how many rows we have in the table
4902 sql_statement = "SELECT count(*) as row_count FROM %s" % (self._table, )
4903 cr.execute(sql_statement)
4904 res = cr.fetchall()
4905 row_count = res[0][0]
4906 if row_count <= max_count:
4907 return # max not reached, nothing to do
4908 self._transient_clean_rows_older_than(cr, 300)
49064909
4907 def _transient_vacuum(self, cr, uid, force=False):4910 def _transient_vacuum(self, cr, uid, force=False):
4908 """Clean the transient records.4911 """Clean the transient records.
@@ -4912,12 +4915,22 @@
4912 Actual cleaning will happen only once every "_transient_check_time" calls.4915 Actual cleaning will happen only once every "_transient_check_time" calls.
4913 This means this method can be called frequently called (e.g. whenever4916 This means this method can be called frequently called (e.g. whenever
4914 a new record is created).4917 a new record is created).
4918 Example with both max_hours and max_count active:
4919 Suppose max_hours = 0.2 (e.g. 12 minutes), max_count = 20, there are 55 rows in the
4920 table, 10 created/changed in the last 5 minutes, an additional 12 created/changed between
4921 5 and 10 minutes ago, the rest created/changed more then 12 minutes ago.
4922 - age based vacuum will leave the 22 rows created/changed in the last 12 minutes
4923 - count based vacuum will wipe out another 12 rows. Not just 2, otherwise each addition
4924 would immediately cause the maximum to be reached again.
4925 - the 10 rows that have been created/changed the last 5 minutes will NOT be deleted
4915 """4926 """
4916 assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name4927 assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name
4928 _transient_check_time = 20 # arbitrary limit on vacuum executions
4917 self._transient_check_count += 14929 self._transient_check_count += 1
4918 if (not force) and (self._transient_check_count % self._transient_check_time):4930 if ((not force)
4919 self._transient_check_count = 04931 and (self._transient_check_count < _transient_check_time)):
4920 return True4932 return True # no vacuum cleaning this time
4933 self._transient_check_count = 0
49214934
4922 # Age-based expiration4935 # Age-based expiration
4923 if self._transient_max_hours:4936 if self._transient_max_hours: