[REF] osv: moved (and adapted) vacuum code to osv_memory.
bzr revid: vmt@openerp.com-20110812113355-lylavdsc3mqjovrj
This commit is contained in:
parent
44d41334d7
commit
2f5e8d48b3
|
@ -42,5 +42,8 @@ import tools
|
||||||
import wizard
|
import wizard
|
||||||
import workflow
|
import workflow
|
||||||
|
|
||||||
|
# The hard-coded super-user id (a.k.a. administrator, or root user).
|
||||||
|
SUPERUSER = 1
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
||||||
|
|
|
@ -19,18 +19,16 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from osv import osv
|
import openerp
|
||||||
from osv.orm import orm_memory
|
|
||||||
|
|
||||||
class osv_memory_autovacuum(osv.osv_memory):
|
class osv_memory_autovacuum(openerp.osv.osv.osv_memory):
|
||||||
|
""" Expose the osv_memory.vacuum() method to the cron jobs mechanism. """
|
||||||
_name = 'osv_memory.autovacuum'
|
_name = 'osv_memory.autovacuum'
|
||||||
|
|
||||||
def power_on(self, cr, uid, context=None):
|
def power_on(self, cr, uid, context=None):
|
||||||
for model in self.pool.obj_list():
|
for model in self.pool.obj_list():
|
||||||
obj = self.pool.get(model)
|
obj = self.pool.get(model)
|
||||||
if isinstance(obj, orm_memory):
|
if obj._transient:
|
||||||
obj.vaccum(cr, uid)
|
obj.vacuum(cr, uid)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
osv_memory_autovacuum()
|
|
||||||
|
|
||||||
|
|
|
@ -284,6 +284,8 @@ def init_module_models(cr, module_name, obj_list):
|
||||||
cr.commit()
|
cr.commit()
|
||||||
for obj in obj_list:
|
for obj in obj_list:
|
||||||
obj._auto_end(cr, {'module': module_name})
|
obj._auto_end(cr, {'module': module_name})
|
||||||
|
if obj._transient:
|
||||||
|
obj.vacuum(cr, openerp.SUPERUSER)
|
||||||
cr.commit()
|
cr.commit()
|
||||||
todo.sort()
|
todo.sort()
|
||||||
for t in todo:
|
for t in todo:
|
||||||
|
|
|
@ -2250,8 +2250,6 @@ class orm_memory(orm_template):
|
||||||
|
|
||||||
_protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count', 'exists']
|
_protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count', 'exists']
|
||||||
_inherit_fields = {}
|
_inherit_fields = {}
|
||||||
_max_count = None
|
|
||||||
_max_hours = None
|
|
||||||
_check_time = 20
|
_check_time = 20
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -2262,43 +2260,12 @@ class orm_memory(orm_template):
|
||||||
super(orm_memory, self).__init__(pool, cr)
|
super(orm_memory, self).__init__(pool, cr)
|
||||||
self.datas = {}
|
self.datas = {}
|
||||||
self.next_id = 0
|
self.next_id = 0
|
||||||
self.check_id = 0
|
|
||||||
self._max_count = config.get('osv_memory_count_limit')
|
|
||||||
self._max_hours = config.get('osv_memory_age_limit')
|
|
||||||
cr.execute('delete from wkf_instance where res_type=%s', (self._name,))
|
cr.execute('delete from wkf_instance where res_type=%s', (self._name,))
|
||||||
|
|
||||||
def _check_access(self, uid, object_id, mode):
|
def _check_access(self, uid, object_id, mode):
|
||||||
if uid != 1 and self.datas[object_id]['internal.create_uid'] != uid:
|
if uid != 1 and self.datas[object_id]['internal.create_uid'] != uid:
|
||||||
raise except_orm(_('AccessError'), '%s access is only allowed on your own records for osv_memory objects except for the super-user' % mode.capitalize())
|
raise except_orm(_('AccessError'), '%s access is only allowed on your own records for osv_memory objects except for the super-user' % mode.capitalize())
|
||||||
|
|
||||||
def vaccum(self, cr, uid, force=False):
|
|
||||||
"""Run the vaccuum cleaning system, expiring and removing old records from the
|
|
||||||
virtual osv_memory tables if the "max count" or "max age" conditions are enabled
|
|
||||||
and have been reached. This method can be called very often (e.g. everytime a record
|
|
||||||
is created), but will only actually trigger the cleanup process once out of
|
|
||||||
"_check_time" times (by default once out of 20 calls)."""
|
|
||||||
self.check_id += 1
|
|
||||||
if (not force) and (self.check_id % self._check_time):
|
|
||||||
return True
|
|
||||||
tounlink = []
|
|
||||||
|
|
||||||
# Age-based expiration
|
|
||||||
if self._max_hours:
|
|
||||||
max = time.time() - self._max_hours * 60 * 60
|
|
||||||
for k,v in self.datas.iteritems():
|
|
||||||
if v['internal.date_access'] < max:
|
|
||||||
tounlink.append(k)
|
|
||||||
self.unlink(cr, ROOT_USER_ID, tounlink)
|
|
||||||
|
|
||||||
# Count-based expiration
|
|
||||||
if self._max_count and len(self.datas) > self._max_count:
|
|
||||||
# sort by access time to remove only the first/oldest ones in LRU fashion
|
|
||||||
records = self.datas.items()
|
|
||||||
records.sort(key=lambda x:x[1]['internal.date_access'])
|
|
||||||
self.unlink(cr, ROOT_USER_ID, [x[0] for x in records[:len(self.datas)-self._max_count]])
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def read(self, cr, user, ids, fields_to_read=None, context=None, load='_classic_read'):
|
def read(self, cr, user, ids, fields_to_read=None, context=None, load='_classic_read'):
|
||||||
if not context:
|
if not context:
|
||||||
context = {}
|
context = {}
|
||||||
|
@ -2352,7 +2319,7 @@ class orm_memory(orm_template):
|
||||||
return object_id
|
return object_id
|
||||||
|
|
||||||
def create(self, cr, user, vals, context=None):
|
def create(self, cr, user, vals, context=None):
|
||||||
self.vaccum(cr, user)
|
self.vacuum(cr, user)
|
||||||
self.next_id += 1
|
self.next_id += 1
|
||||||
id_new = self.next_id
|
id_new = self.next_id
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,13 @@
|
||||||
#.apidoc title: Objects Services (OSV)
|
#.apidoc title: Objects Services (OSV)
|
||||||
|
|
||||||
import orm
|
import orm
|
||||||
|
import openerp
|
||||||
import openerp.netsvc as netsvc
|
import openerp.netsvc as netsvc
|
||||||
import openerp.pooler as pooler
|
import openerp.pooler as pooler
|
||||||
import openerp.sql_db as sql_db
|
import openerp.sql_db as sql_db
|
||||||
import logging
|
import logging
|
||||||
from psycopg2 import IntegrityError, errorcodes
|
from psycopg2 import IntegrityError, errorcodes
|
||||||
|
from openerp.tools.config import config
|
||||||
from openerp.tools.func import wraps
|
from openerp.tools.func import wraps
|
||||||
from openerp.tools.translate import translate
|
from openerp.tools.translate import translate
|
||||||
from openerp.osv.orm import MetaModel
|
from openerp.osv.orm import MetaModel
|
||||||
|
@ -203,12 +205,70 @@ class osv_memory(orm.orm):
|
||||||
""" Deprecated class. """
|
""" Deprecated class. """
|
||||||
__metaclass__ = MetaModel
|
__metaclass__ = MetaModel
|
||||||
_register = False # Set to false if the model shouldn't be automatically discovered.
|
_register = False # Set to false if the model shouldn't be automatically discovered.
|
||||||
|
_transient = True
|
||||||
|
_max_count = None
|
||||||
|
_max_hours = None
|
||||||
|
_check_time = 20
|
||||||
|
|
||||||
|
def __init__(self, pool, cr):
|
||||||
|
super(osv_memory, self).__init__(pool, cr)
|
||||||
|
self.check_id = 0
|
||||||
|
self._max_count = config.get('osv_memory_count_limit')
|
||||||
|
self._max_hours = config.get('osv_memory_age_limit')
|
||||||
|
|
||||||
|
def _clean_transient_rows_older_than(self, cr, seconds):
|
||||||
|
if not self._log_access:
|
||||||
|
self.logger = logging.getLogger('orm').warning(
|
||||||
|
"Transient model without write_date: %s" % (self._name,))
|
||||||
|
return
|
||||||
|
|
||||||
|
cr.execute("SELECT id FROM " + self._table + " WHERE "
|
||||||
|
"COALESCE(write_date, create_date, now())::timestamp < "
|
||||||
|
"(now() - interval %s)", ("%s seconds" % seconds,))
|
||||||
|
ids = [x[0] for x in cr.fetchall()]
|
||||||
|
self.unlink(cr, openerp.SUPERUSER, ids)
|
||||||
|
|
||||||
|
def _clean_old_transient_rows(self, cr, count):
|
||||||
|
if not self._log_access:
|
||||||
|
self.logger = logging.getLogger('orm').warning(
|
||||||
|
"Transient model without write_date: %s" % (self._name,))
|
||||||
|
return
|
||||||
|
|
||||||
|
cr.execute(
|
||||||
|
"SELECT id, COALESCE(write_date, create_date, now())::timestamp"
|
||||||
|
" AS t FROM " + self._table +
|
||||||
|
" ORDER BY t LIMIT %s", (count,))
|
||||||
|
ids = [x[0] for x in cr.fetchall()]
|
||||||
|
self.unlink(cr, openerp.SUPERUSER, ids)
|
||||||
|
|
||||||
|
def vacuum(self, cr, uid, force=False):
|
||||||
|
""" Run the vacuum cleaner, i.e. unlink old records from the
|
||||||
|
virtual osv_memory tables if the "max count" or "max age" conditions are enabled
|
||||||
|
and have been reached. This method can be called very often (e.g. everytime a record
|
||||||
|
is created), but will only actually trigger the cleanup process once out of
|
||||||
|
"_check_time" times (by default once out of 20 calls)."""
|
||||||
|
self.check_id += 1
|
||||||
|
if (not force) and (self.check_id % self._check_time):
|
||||||
|
self.check_id = 0
|
||||||
|
return True
|
||||||
|
tounlink = []
|
||||||
|
|
||||||
|
# Age-based expiration
|
||||||
|
if self._max_hours:
|
||||||
|
self._clean_transient_rows_older_than(cr, self._max_hours * 60 * 60)
|
||||||
|
|
||||||
|
# Count-based expiration
|
||||||
|
if self._max_count:
|
||||||
|
self._clean_old_transient_rows(cr, self._max_count)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class osv(orm.orm):
|
class osv(orm.orm):
|
||||||
""" Deprecated class. """
|
""" Deprecated class. """
|
||||||
__metaclass__ = MetaModel
|
__metaclass__ = MetaModel
|
||||||
_register = False # Set to false if the model shouldn't be automatically discovered.
|
_register = False # Set to false if the model shouldn't be automatically discovered.
|
||||||
|
_transient = False
|
||||||
|
|
||||||
|
|
||||||
def start_object_proxy():
|
def start_object_proxy():
|
||||||
|
|
Loading…
Reference in New Issue