book/line: logging, model: cache-write skip existing values
This commit is contained in:
parent
179543bcf0
commit
03324d5944
4 changed files with 81 additions and 35 deletions
40
book.py
40
book.py
|
@ -11,12 +11,15 @@ from trytond.transaction import Transaction
|
|||
from trytond.pool import Pool
|
||||
from trytond.report import Report
|
||||
from decimal import Decimal
|
||||
from datetime import date
|
||||
from datetime import date, datetime
|
||||
from sql.aggregate import Sum
|
||||
from sql.conditionals import Case
|
||||
from .model import order_name_hierarchical, sub_ids_hierarchical, \
|
||||
AnyInArray, CACHEKEY_CURRENCY, CACHEKEY_CASHBOOK
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
STATES = {
|
||||
'readonly': Eval('state', '') != 'open',
|
||||
|
@ -262,15 +265,15 @@ 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')
|
||||
# ~ 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')])]
|
||||
# ~ 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):
|
||||
|
@ -362,6 +365,12 @@ 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']}
|
||||
|
@ -381,7 +390,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
|
|||
query = [{
|
||||
'model': 'cashbook.line',
|
||||
'query': [('cashbook.parent', 'child_of', [x.id])],
|
||||
'cachekey': CACHEKEY_CASHBOOK % x.id,
|
||||
#'cachekey': CACHEKEY_CASHBOOK % x.id,
|
||||
}, {
|
||||
'model': 'currency.currency.rate',
|
||||
'query': [('currency.id', '=', x.currency.id)],
|
||||
|
@ -392,9 +401,15 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
|
|||
}
|
||||
|
||||
# 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
|
||||
|
@ -430,7 +445,10 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
|
|||
result['balance_ref'][record[0]] += Currency.compute(
|
||||
record[2], record[5], record[3])
|
||||
|
||||
MemCache.store_result(cashbooks, cache_keys, result)
|
||||
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')
|
||||
|
|
22
line.py
22
line.py
|
@ -1008,9 +1008,9 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
))
|
||||
records = super(Line, cls).create(vlist)
|
||||
|
||||
for record in records:
|
||||
for x in record.cashbook.get_cachekeys_by_hierarchy():
|
||||
MemCache.record_update(x, record)
|
||||
# ~ for record in records:
|
||||
# ~ for x in record.cashbook.get_cachekeys_by_hierarchy():
|
||||
# ~ MemCache.record_update(x, record)
|
||||
return records
|
||||
|
||||
@classmethod
|
||||
|
@ -1066,11 +1066,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)
|
||||
# ~ 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):
|
||||
|
@ -1079,9 +1079,9 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
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)
|
||||
# ~ 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
|
||||
|
|
44
model.py
44
model.py
|
@ -7,12 +7,14 @@ 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 datetime import timedelta
|
||||
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
|
||||
import copy, logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
ENABLE_CACHE = True
|
||||
|
@ -91,19 +93,26 @@ class MemCache(Model):
|
|||
return copy.deepcopy(cls._cashbook_value_cache.get(cache_key))
|
||||
|
||||
@classmethod
|
||||
def store_result(cls, records, cache_keys, values):
|
||||
def store_result(cls, records, cache_keys, values, skip_records=[]):
|
||||
""" store result to cache
|
||||
"""
|
||||
if ENABLE_CACHE == False:
|
||||
return
|
||||
for record in records:
|
||||
if record not in skip_records:
|
||||
continue
|
||||
data = {x:values[x][record.id]
|
||||
for x in values.keys()
|
||||
if record.id in values[x].keys()}
|
||||
cls._cashbook_value_cache.set(cache_keys[record.id], copy.deepcopy(data))
|
||||
print('\n## SYNC-GO-1')
|
||||
# ~ logger.info('memcache-VALUE-SET %(time)s key=%(key)s' % {
|
||||
# ~ 'time': datetime.now().isoformat(),
|
||||
# ~ 'key': cache_keys[record.id],
|
||||
# ~ })
|
||||
cls._cashbook_value_cache.sync(Transaction())
|
||||
print('-- SYNC-FERTIG-1')
|
||||
# ~ logger.info('memcache-VALUE-SYNC %(time)s' % {
|
||||
# ~ 'time': datetime.now().isoformat(),
|
||||
# ~ })
|
||||
|
||||
@classmethod
|
||||
def store_value(cls, cache_key, values):
|
||||
|
@ -112,9 +121,10 @@ class MemCache(Model):
|
|||
if ENABLE_CACHE == False:
|
||||
return
|
||||
cls._cashbook_value_cache.set(cache_key, copy.deepcopy(values))
|
||||
print('\n## SYNC-GO-2')
|
||||
cls._cashbook_value_cache.sync(Transaction())
|
||||
print('-- SYNC-FERTIG-2')
|
||||
# ~ 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):
|
||||
|
@ -135,7 +145,15 @@ 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)
|
||||
|
||||
|
@ -149,6 +167,11 @@ 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)
|
||||
|
||||
|
@ -192,6 +215,11 @@ 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
|
||||
|
|
|
@ -190,11 +190,11 @@ 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
|
||||
])
|
||||
# ~ 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):
|
||||
|
|
Loading…
Reference in a new issue