[cache] fix a cache issue with an entity created without relation cache prefill
Prefilling the relation cache has its benefits sometimes, but for
massive imports it may be a memory hog.
The caches should be kept coherent even if there was no prefill.
Closes #3828155.
--- a/server/repository.py Wed Apr 23 17:21:07 2014 +0200
+++ b/server/repository.py Tue May 13 13:12:16 2014 +0200
@@ -1452,11 +1452,7 @@
if relcache is not None:
session.update_rel_cache_del(entity.eid, attr, prevvalue)
del_existing_rel_if_needed(session, entity.eid, attr, value)
- if relcache is not None:
- session.update_rel_cache_add(entity.eid, attr, value)
- else:
- entity.cw_set_relation_cache(attr, 'subject',
- session.eid_rset(value))
+ session.update_rel_cache_add(entity.eid, attr, value)
hm.call_hooks('after_add_relation', session,
eidfrom=entity.eid, rtype=attr, eidto=value)
finally:
--- a/test/data/schema.py Wed Apr 23 17:21:07 2014 +0200
+++ b/test/data/schema.py Tue May 13 13:12:16 2014 +0200
@@ -60,7 +60,7 @@
class Produit(EntityType):
- fabrique_par = SubjectRelation('Usine', cardinality='1*')
+ fabrique_par = SubjectRelation('Usine', cardinality='1*', inlined=True)
class Usine(EntityType):
--- a/test/unittest_entity.py Wed Apr 23 17:21:07 2014 +0200
+++ b/test/unittest_entity.py Tue May 13 13:12:16 2014 +0200
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -44,6 +44,18 @@
for cls in self.vreg['etypes'].iter_classes():
cls.fetch_attrs, cls.cw_fetch_order = self.backup_dict[cls]
+ def test_no_prefill_related_cache_bug(self):
+ session = self.session
+ usine = session.create_entity('Usine', lieu=u'Montbeliard')
+ produit = session.create_entity('Produit')
+ # usine was prefilled in glob_add_entity
+ # let's simulate produit creation without prefill
+ produit._cw_related_cache.clear()
+ # use add_relations
+ session.add_relations([('fabrique_par', [(produit.eid, usine.eid)])])
+ self.assertEqual(1, len(usine.reverse_fabrique_par))
+ self.assertEqual(1, len(produit.fabrique_par))
+
def test_boolean_value(self):
e = self.vreg['etypes'].etype_class('CWUser')(self.request())
self.assertTrue(e)