One of the main issue with ormcache is that the invalidation clears everything, meaning that some value, slow to compute but with a long lifetime, can be removed from the cache because an easy to invalidate value is cleared, like after writting or creating a product has an example. Most example in the code will try to invalidate the cache of the models doing something like `env['ir.qweb'].clear_caches()` but it is finally equivalent to `env.registry.clear_cache()`, and cross worker. The idea is to have multiple cache, maybe with specific sizes for a specific purpose. Having one per model is maybe a bad idea because it will be difficult to size the LRU correcly, and it is too dynamic. Checking invalidation may be expensive. The proposed solution is closed allow a limited number of named caches, using onse sequence per cache. This is actually close to the cache_longterm. We want to discourage using a specific cache for one use case in the buisness code. Adding a cache shouldn't be something easy, doable in stable. Note that we could also change the invalisation mecanism using an insert only table. We an check the sequence of this table, but also fetch all invalidation messages. Another possible improvement, especially if we have more than x cache is to have a global sequence, checking signaling would mean to check the main sequence, and only the other ones if the main one changed. Note that this poc is inspired from the long term cache but not all use case where applie yet. Part-of: odoo/odoo#119813
74 lines
2.6 KiB
Python
74 lines
2.6 KiB
Python
# -*- encoding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo import api, fields, models, tools, _
|
|
import odoo.addons
|
|
|
|
import logging
|
|
import sys
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
def get_precision(application):
|
|
_logger.warning("Deprecated call to decimal_precision.get_precision(<application>), use digits=<application> instead")
|
|
return application
|
|
|
|
|
|
class DecimalPrecision(models.Model):
|
|
_name = 'decimal.precision'
|
|
_description = 'Decimal Precision'
|
|
|
|
name = fields.Char('Usage', required=True)
|
|
digits = fields.Integer('Digits', required=True, default=2)
|
|
|
|
_sql_constraints = [
|
|
('name_uniq', 'unique (name)', """Only one value can be defined for each given usage!"""),
|
|
]
|
|
|
|
@api.model
|
|
@tools.ormcache('application')
|
|
def precision_get(self, application):
|
|
self.flush_model(['name', 'digits'])
|
|
self.env.cr.execute('select digits from decimal_precision where name=%s', (application,))
|
|
res = self.env.cr.fetchone()
|
|
return res[0] if res else 2
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
res = super(DecimalPrecision, self).create(vals_list)
|
|
self.env.registry.clear_cache()
|
|
return res
|
|
|
|
def write(self, data):
|
|
res = super(DecimalPrecision, self).write(data)
|
|
self.env.registry.clear_cache()
|
|
return res
|
|
|
|
def unlink(self):
|
|
res = super(DecimalPrecision, self).unlink()
|
|
self.env.registry.clear_cache()
|
|
return res
|
|
|
|
@api.onchange('digits')
|
|
def _onchange_digits_warning(self):
|
|
if self.digits < self._origin.digits:
|
|
return {
|
|
'warning': {
|
|
'title': _("Warning for %s", self.name),
|
|
'message': _(
|
|
"The precision has been reduced for %s.\n"
|
|
"Note that existing data WON'T be updated by this change.\n\n"
|
|
"As decimal precisions impact the whole system, this may cause critical issues.\n"
|
|
"E.g. reducing the precision could disturb your financial balance.\n\n"
|
|
"Therefore, changing decimal precisions in a running database is not recommended.",
|
|
self.name,
|
|
)
|
|
}
|
|
}
|
|
|
|
# compatibility for decimal_precision.get_precision(): expose the module in addons namespace
|
|
dp = sys.modules['odoo.addons.base.models.decimal_precision']
|
|
odoo.addons.decimal_precision = dp
|
|
sys.modules['odoo.addons.decimal_precision'] = dp
|
|
sys.modules['openerp.addons.decimal_precision'] = dp
|