Manage Cache in Transaction

issue6216
review33021002
This commit is contained in:
Cédric Krier
2017-02-02 12:04:27 +01:00
parent aec4208225
commit cdc5952145
8 changed files with 19 additions and 19 deletions
+1
View File
@@ -1,3 +1,4 @@
* Manage Cache in Transaction
* Allow to register multiple exit functions on Transaction
* Return 429 status when too many login attempts
* Add set_rpc on Field
+2
View File
@@ -13,6 +13,8 @@ be unique and it's used to identify the cache. We usually use
be used to limit the number of values cached and the `context` parameter
is used to indicate if the cache depends on the user context and is true
by default.
The cache is cleaned on :class:`Transaction` starts and resets on
:class:`Transaction` commit or rollback.
.. warning::
As there is no deepcopy of the values cached, they must never be mutated
+2 -2
View File
@@ -105,7 +105,7 @@ class MemoryCache(BaseCache):
@staticmethod
def clean(dbname):
with Transaction().new_transaction() as transaction,\
with Transaction().new_transaction(_nocache=True) as transaction,\
transaction.connection.cursor() as cursor:
table = Table('ir_cache')
cursor.execute(*table.select(table.timestamp, table.name))
@@ -129,7 +129,7 @@ class MemoryCache(BaseCache):
@staticmethod
def resets(dbname):
table = Table('ir_cache')
with Transaction().new_transaction() as transaction,\
with Transaction().new_transaction(_nocache=True) as transaction,\
transaction.connection.cursor() as cursor,\
Cache._resets_lock:
Cache._resets.setdefault(dbname, set())
-3
View File
@@ -14,7 +14,6 @@ from ..transaction import Transaction
from ..pool import Pool
from .. import backend
from ..config import config
from ..cache import Cache
from ..sendmail import sendmail
__all__ = [
@@ -181,7 +180,6 @@ class Cron(ModelSQL, ModelView):
def run(cls, db_name):
now = datetime.datetime.now()
with Transaction().start(db_name, 0) as transaction:
Cache.clean(db_name)
transaction.database.lock(transaction.connection, cls._table)
crons = cls.search([
('number_calls', '!=', 0),
@@ -214,4 +212,3 @@ class Cron(ModelSQL, ModelView):
except Exception:
transaction.rollback()
logger.error('Running cron %s', cron.id, exc_info=True)
Cache.resets(db_name)
-2
View File
@@ -17,7 +17,6 @@ from sql.functions import CurrentTimestamp
import trytond.tools as tools
from trytond.config import config
from trytond.transaction import Transaction
from trytond.cache import Cache
from trytond import backend
import trytond.convert as convert
@@ -446,7 +445,6 @@ def load_modules(database_name, pool, update=None, lang=None):
Module.update_list()
# Need to commit to unlock SQLite database
transaction.commit()
Cache.resets(database_name)
if not Transaction().connection:
with Transaction().start(database_name, 0):
-6
View File
@@ -13,7 +13,6 @@ from trytond import backend
from trytond.config import config
from trytond import __version__
from trytond.transaction import Transaction
from trytond.cache import Cache
from trytond.exceptions import (
UserError, UserWarning, ConcurrencyException, LoginException,
RateLimitException)
@@ -57,9 +56,6 @@ def login(request, database_name, user, parameters, language=None):
except RateLimitException:
session = None
code = 429
with Transaction().start(database_name, 0):
Cache.clean(database_name)
Cache.resets(database_name)
msg = 'successful login' if session else 'bad login or password'
logger.info('%s \'%s\' from %s using %s on database \'%s\'',
msg, user, request.remote_addr, request.scheme, database_name)
@@ -156,7 +152,6 @@ def _dispatch(request, pool, *args, **kwargs):
for count in range(config.getint('database', 'retry'), -1, -1):
with Transaction().start(pool.database_name, user,
readonly=rpc.readonly) as transaction:
Cache.clean(pool.database_name)
try:
c_args, c_kwargs, transaction.context, transaction.timestamp \
= rpc.convert(obj, *args, **kwargs)
@@ -187,7 +182,6 @@ def _dispatch(request, pool, *args, **kwargs):
raise
# Need to commit to unlock SQLite database
transaction.commit()
Cache.resets(pool.database_name)
if request.authorization.type == 'session':
try:
with Transaction().start(pool.database_name, 0) as transaction:
-3
View File
@@ -16,7 +16,6 @@ from trytond import security, backend
from trytond.pool import Pool
from trytond.transaction import Transaction
from trytond.config import config
from trytond.cache import Cache
logger = logging.getLogger(__name__)
@@ -123,7 +122,6 @@ def with_transaction(readonly=None):
pool.database_name, 0, readonly=readonly_
) as transaction:
try:
Cache.clean(pool.database_name)
result = func(request, pool, *args, **kwargs)
except DatabaseOperationalError:
if count and not readonly_:
@@ -136,7 +134,6 @@ def with_transaction(readonly=None):
raise
# Need to commit to unlock SQLite database
transaction.commit()
Cache.resets(pool.database_name)
return result
return wrapper
return decorator
+14 -3
View File
@@ -73,7 +73,7 @@ class Transaction(object):
LRUDict(config.getint('cache', 'model')))
def start(self, database_name, user, readonly=False, context=None,
close=False, autocommit=False):
close=False, autocommit=False, _nocache=False):
'''
Start transaction
'''
@@ -100,6 +100,10 @@ class Transaction(object):
self.timestamp = {}
self.counter = 0
self._datamanagers = []
self._nocache = _nocache
if not _nocache:
from trytond.cache import Cache
Cache.clean(database.name)
return self
def __enter__(self):
@@ -170,11 +174,12 @@ class Transaction(object):
self._local.transactions.append(transaction)
return transaction
def new_transaction(self, autocommit=False, readonly=False):
def new_transaction(self, autocommit=False, readonly=False,
_nocache=False):
transaction = Transaction(new=True)
return transaction.start(self.database.name, self.user,
context=self.context, close=self.close, readonly=readonly,
autocommit=autocommit)
autocommit=autocommit, _nocache=_nocache)
def commit(self):
try:
@@ -197,6 +202,9 @@ class Transaction(object):
logger.critical('A datamanager raised an exception in'
' tpc_finish, the data might be inconsistant',
exc_info=True)
if not self._nocache:
from trytond.cache import Cache
Cache.resets(self.database.name)
def rollback(self):
for cache in self.cache.itervalues():
@@ -204,6 +212,9 @@ class Transaction(object):
for datamanager in self._datamanagers:
datamanager.tpc_abort(self)
self.connection.rollback()
if not self._nocache:
from trytond.cache import Cache
Cache.resets(self.database.name)
def join(self, datamanager):
try: