remove logging, add config-settings for caching, add docs

This commit is contained in:
Frederik Jaeckel 2023-03-05 10:20:02 +01:00
parent 03324d5944
commit 78f160bf0b
6 changed files with 47 additions and 96 deletions

41
book.py
View file

@ -10,15 +10,20 @@ from trytond.i18n import gettext
from trytond.transaction import Transaction
from trytond.pool import Pool
from trytond.report import Report
from trytond.config import config
from decimal import Decimal
from datetime import date, datetime
from datetime import date
from sql.aggregate import Sum
from sql.conditionals import Case
from .model import order_name_hierarchical, sub_ids_hierarchical, \
AnyInArray, CACHEKEY_CURRENCY, CACHEKEY_CASHBOOK
AnyInArray, CACHEKEY_CURRENCY
import logging
logger = logging.getLogger(__name__)
# enable/disable caching of cachekey for 'currency.rate'
if config.get('cashbook', 'cache_currency', default='yes').lower() in ['yes', '1', 'true']:
ENA_CURRKEY = True
else :
ENA_CURRKEY = False
STATES = {
@ -265,16 +270,6 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
}
return recname
# ~ def get_cachekeys_by_hierarchy(self):
# ~ """ generate keys for all cashbooks above us
# ~ """
# ~ CBook = Pool().get('cashbook.book')
# ~ return [CACHEKEY_CASHBOOK % x.id
# ~ for x in CBook.search([
# ~ ('parent', 'parent_of', [self.id]),
# ~ ], order=[('id', 'ASC')])]
@classmethod
def get_balance_of_cashbook_sql(cls):
""" sql for balance of a single cashbook
@ -365,12 +360,6 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
cursor = Transaction().connection.cursor()
context = Transaction().context
logger.warning('## get_balance_cashbook-GO %(time)s %(ids)s %(name)s' % {
'time': datetime.now().isoformat(),
'ids': str([x.id for x in cashbooks]),
'name': names,
})
result = {
x:{y.id: Decimal('0.0') for y in cashbooks}
for x in ['balance', 'balance_all', 'balance_ref']}
@ -390,26 +379,19 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
query = [{
'model': 'cashbook.line',
'query': [('cashbook.parent', 'child_of', [x.id])],
#'cachekey': CACHEKEY_CASHBOOK % x.id,
}, {
'model': 'currency.currency.rate',
'query': [('currency.id', '=', x.currency.id)],
'cachekey': CACHEKEY_CURRENCY % x.currency.id,
'cachekey' if ENA_CURRKEY else 'disabled': CACHEKEY_CURRENCY % x.currency.id,
}, ],
addkeys = [query_date.isoformat()])
for x in cashbooks
}
# read from cache
logger.warning('## get_balance_cashbook-KEYS %(time)s' % {
'time': datetime.now().isoformat(),
})
(todo_cashbook, result) = MemCache.read_from_cache(
cashbooks, cache_keys, names, result)
if len(todo_cashbook) == 0:
logger.warning('## get_balance_cashbook-HIT %(time)s' % {
'time': datetime.now().isoformat(),
})
return result
# query balances of cashbooks and sub-cashbooks
@ -446,9 +428,6 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
record[2], record[5], record[3])
MemCache.store_result(cashbooks, cache_keys, result, todo_cashbook)
logger.warning('## get_balance_cashbook-END %(time)s' % {
'time': datetime.now().isoformat(),
})
return result
@fields.depends('btype')

21
docs/settings.txt Normal file
View file

@ -0,0 +1,21 @@
settings in tytond.conf
[cashbook]
# enable caching of values, stores values between
# browser requests, speeds up the retrieval of data.
# default: yes
memcache = yes
# Enables synchronization of the cache between multiple
# server instances.
# default: yes
# Requires the setting :
# [cache]
# clean_timeout=0
sync = yes
# Enables caching of the cache key for currency rates.
# Reduces the time required to determine the cache
# key for currency values.
# default: yes
cache_currency = yes

25
line.py
View file

@ -16,7 +16,6 @@ from sql.functions import DatePart
from sql.conditionals import Case
from .book import sel_state_book
from .mixin import SecondCurrencyMixin, MemCacheIndexMx
from .model import CACHEKEY_CASHBOOK
sel_payee = [
@ -180,8 +179,6 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
states={'invisible': True}, model_name='res.user'),
'on_change_with_owner_cashbook')
#image = fields.Binary...
@classmethod
def __register__(cls, module_name):
super(Line, cls).__register__(module_name)
@ -984,8 +981,6 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
def create(cls, vlist):
""" add debit/credit
"""
MemCache = Pool().get('cashbook.memcache')
vlist = [x.copy() for x in vlist]
for values in vlist:
values.update(cls.add_values_from_splitlines(values))
@ -1006,20 +1001,13 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
'descr': values.get('description', '-'),
},
))
records = super(Line, cls).create(vlist)
# ~ for record in records:
# ~ for x in record.cashbook.get_cachekeys_by_hierarchy():
# ~ MemCache.record_update(x, record)
return records
return super(Line, cls).create(vlist)
@classmethod
def write(cls, *args):
""" deny update if cashbook.line!='open',
add or update debit/credit
"""
MemCache = Pool().get('cashbook.memcache')
actions = iter(args)
to_write = []
for lines, values in zip(actions, actions):
@ -1066,22 +1054,11 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
super(Line, cls).write(*to_write)
# ~ actions = iter(to_write)
# ~ for records, values in zip(actions, actions):
# ~ for record in records:
# ~ for x in record.cashbook.get_cachekeys_by_hierarchy():
# ~ MemCache.record_update(x, record)
@classmethod
def delete(cls, lines):
""" deny delete if book is not 'open' or wf is not 'edit'
"""
MemCache = Pool().get('cashbook.memcache')
cls.check_permission_delete(lines)
# ~ for line in lines:
# ~ for x in line.cashbook.get_cachekeys_by_hierarchy():
# ~ MemCache.record_update(x, None)
super(Line, cls).delete(lines)
# end Line

View file

@ -7,19 +7,25 @@ from trytond.model import MultiValueMixin, ValueMixin, fields, Unique, Model
from trytond.transaction import Transaction
from trytond.pool import Pool
from trytond.cache import MemoryCache
from trytond.config import config
from datetime import timedelta, datetime
from decimal import Decimal
from sql import With, Literal
from sql.functions import Function
from sql.conditionals import Coalesce
import copy, logging
import copy
logger = logging.getLogger(__name__)
if config.get('cashbook', 'memcache', default='yes').lower() in ['yes', '1', 'true']:
ENABLE_CACHE = True
else:
ENABLE_CACHE = False
if config.get('cashbook', 'sync', default='yes').lower() in ['yes', '1', 'true']:
ENABLE_CACHESYNC = True
else:
ENABLE_CACHESYNC = False
ENABLE_CACHE = True
CACHEKEY_CURRENCY = 'currency-%s'
CACHEKEY_CASHBOOK = 'cashbook-%s'
class ArrayAgg(Function):
@ -105,14 +111,8 @@ class MemCache(Model):
for x in values.keys()
if record.id in values[x].keys()}
cls._cashbook_value_cache.set(cache_keys[record.id], copy.deepcopy(data))
# ~ logger.info('memcache-VALUE-SET %(time)s key=%(key)s' % {
# ~ 'time': datetime.now().isoformat(),
# ~ 'key': cache_keys[record.id],
# ~ })
if ENABLE_CACHESYNC == True:
cls._cashbook_value_cache.sync(Transaction())
# ~ logger.info('memcache-VALUE-SYNC %(time)s' % {
# ~ 'time': datetime.now().isoformat(),
# ~ })
@classmethod
def store_value(cls, cache_key, values):
@ -121,10 +121,6 @@ class MemCache(Model):
if ENABLE_CACHE == False:
return
cls._cashbook_value_cache.set(cache_key, copy.deepcopy(values))
# ~ logger.info('memcache-VALUE-SET %(time)s key=%(key)s' % {
# ~ 'time': datetime.now().isoformat(),
# ~ 'key': cache_key,
# ~ })
@classmethod
def read_from_cache(cls, records, cache_keys, names, result):
@ -145,15 +141,7 @@ class MemCache(Model):
if result[name][record.id] is None:
result[name][record.id] = Decimal('0.0')
result[name][record.id] += values[name]
# ~ logger.info('memcache-VALUE-READ-HIT %(time)s key=%(key)s' % {
# ~ 'time': datetime.now().isoformat(),
# ~ 'key': cache_keys[record.id],
# ~ })
else :
# ~ logger.info('memcache-VALUE-READ-FAIL %(time)s key=%(key)s' % {
# ~ 'time': datetime.now().isoformat(),
# ~ 'key': cache_keys[record.id],
# ~ })
todo_records.append(record)
return (todo_records, result)
@ -167,11 +155,6 @@ class MemCache(Model):
if ENABLE_CACHE == False:
return '-'
# ~ logger.info('memcache-KEY %(time)s name=%(name)s record=%(record)s' % {
# ~ 'time': datetime.now().isoformat(),
# ~ 'name': name,
# ~ 'record': str(record),
# ~ })
fname = [name, str(record.id)]
fname.extend(addkeys)
@ -215,11 +198,6 @@ class MemCache(Model):
if 'cachekey' in line.keys():
key = cls.store_value(line['cachekey'], fname[-1])
# ~ logger.info('memcache-KEY-RESULT %(time)s name=%(name)s result=%(result)s' % {
# ~ 'time': datetime.now().isoformat(),
# ~ 'name': name,
# ~ 'result': '-'.join(fname),
# ~ })
return '-'.join(fname)
@classmethod
@ -238,6 +216,8 @@ class MemCache(Model):
def record_update(cls, cache_key, record):
""" update cache-value
"""
if ENABLE_CACHE == False:
return
cls.store_value(cache_key,
cls.genkey(record.id, record.write_date, record.create_date)
if record is not None else None)

View file

@ -99,7 +99,7 @@ setup(name='%s_%s' % (PREFIX, MODULE),
package_data={
'trytond.modules.%s' % MODULE: (info.get('xml', [])
+ ['tryton.cfg', 'locale/*.po', 'tests/*.py',
'view/*.xml', 'icon/*.svg',
'view/*.xml', 'icon/*.svg', 'docs/*.txt',
'report/*.fods', 'versiondep.txt', 'README.rst']),
},

View file

@ -9,7 +9,6 @@ from trytond.transaction import Transaction
from trytond.exceptions import UserError
from datetime import date
from decimal import Decimal
from trytond.modules.cashbook.model import CACHEKEY_CASHBOOK
class BookTestCase(ModuleTestCase):
@ -190,11 +189,6 @@ class BookTestCase(ModuleTestCase):
self.assertEqual(book.rec_name, 'Level 1')
self.assertEqual(len(book.childs), 1)
self.assertEqual(book.childs[0].rec_name, 'Level 1/Level 2 | 0.00 usd | Open')
# ~ self.assertEqual(book.get_cachekeys_by_hierarchy(), [CACHEKEY_CASHBOOK % book.id])
# ~ self.assertEqual(book.childs[0].get_cachekeys_by_hierarchy(), [
# ~ CACHEKEY_CASHBOOK % book.id,
# ~ CACHEKEY_CASHBOOK % book.childs[0].id
# ~ ])
@with_transaction()
def test_book_deny_delete_open(self):