Merge ~cjwatson/launchpad:remove-storm-workarounds into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 4042fcdc849e26cd1048a3c00188a5004886fe0d
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:remove-storm-workarounds
Merge into: launchpad:master
Diff against target: 92 lines (+13/-17)
2 files modified
lib/lp/registry/model/product.py (+9/-8)
lib/lp/registry/tests/test_product.py (+4/-9)
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+373695@code.launchpad.net

Commit message

Remove workarounds for Storm reference cycles

https://code.launchpad.net/~cjwatson/storm/more-weakrefs/+merge/365639
fixed a long-standing Storm bug that sometimes resulted in GC cycles.
We've had this fix deployed in Launchpad for a while with no problems,
so it now makes sense to remove workarounds for it in favour of more
natural code.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/lib/lp/registry/model/product.py b/lib/lp/registry/model/product.py
index 97c6138..8b47075 100644
--- a/lib/lp/registry/model/product.py
+++ b/lib/lp/registry/model/product.py
@@ -42,6 +42,8 @@ from storm.expr import (
42 SQL,42 SQL,
43 )43 )
44from storm.locals import (44from storm.locals import (
45 Int,
46 List,
45 Store,47 Store,
46 Unicode,48 Unicode,
47 )49 )
@@ -363,6 +365,11 @@ class Product(SQLBase, BugTargetBase, MakesAnnouncements,
363 name='remote_product', allow_none=True, default=None)365 name='remote_product', allow_none=True, default=None)
364 vcs = EnumCol(enum=VCSType, notNull=False)366 vcs = EnumCol(enum=VCSType, notNull=False)
365367
368 # Cache of AccessPolicy.ids that convey launchpad.LimitedView.
369 # Unlike artifacts' cached access_policies, an AccessArtifactGrant
370 # to an artifact in the policy is sufficient for access.
371 access_policies = List(type=Int())
372
366 @property373 @property
367 def displayname(self):374 def displayname(self):
368 return self.display_name375 return self.display_name
@@ -759,18 +766,12 @@ class Product(SQLBase, BugTargetBase, MakesAnnouncements,
759 # Security was somehow left around when a project was766 # Security was somehow left around when a project was
760 # transitioned to Proprietary.767 # transitioned to Proprietary.
761 if self.information_type in PROPRIETARY_INFORMATION_TYPES:768 if self.information_type in PROPRIETARY_INFORMATION_TYPES:
762 policy_ids = [769 self.access_policies = [
763 policy.id for policy in770 policy.id for policy in
764 getUtility(IAccessPolicySource).find(771 getUtility(IAccessPolicySource).find(
765 [(self, type) for type in PROPRIETARY_INFORMATION_TYPES])]772 [(self, type) for type in PROPRIETARY_INFORMATION_TYPES])]
766 else:773 else:
767 policy_ids = None774 self.access_policies = None
768 # XXX wgrant 2015-06-30: We must set this manually, as Storm's
769 # MutableValueVariable causes a PostgresConnection to be
770 # uncollectable in some circumstances involving a Store.reset.
771 Store.of(self).execute(
772 "UPDATE Product SET access_policies = ? WHERE id = ?",
773 (policy_ids, self.id))
774775
775 def _pruneUnusedPolicies(self):776 def _pruneUnusedPolicies(self):
776 allowed_bug_types = set(777 allowed_bug_types = set(
diff --git a/lib/lp/registry/tests/test_product.py b/lib/lp/registry/tests/test_product.py
index 7387ed2..6dc0e96 100644
--- a/lib/lp/registry/tests/test_product.py
+++ b/lib/lp/registry/tests/test_product.py
@@ -495,29 +495,24 @@ class TestProduct(TestCaseWithFactory):
495 # principal LimitedView on the Product.495 # principal LimitedView on the Product.
496 aps = getUtility(IAccessPolicySource)496 aps = getUtility(IAccessPolicySource)
497497
498 def get_aps(product):
499 return Store.of(product).execute(
500 "SELECT access_policies FROM product WHERE id = ?",
501 (product.id,)).get_one()[0]
502
503 # Public projects don't need a cache.498 # Public projects don't need a cache.
504 product = self.factory.makeProduct()499 product = self.factory.makeProduct()
505 naked_product = removeSecurityProxy(product)500 naked_product = removeSecurityProxy(product)
506 self.assertContentEqual(501 self.assertContentEqual(
507 [InformationType.USERDATA, InformationType.PRIVATESECURITY],502 [InformationType.USERDATA, InformationType.PRIVATESECURITY],
508 [p.type for p in aps.findByPillar([product])])503 [p.type for p in aps.findByPillar([product])])
509 self.assertIs(None, get_aps(product))504 self.assertIs(None, naked_product.access_policies)
510505
511 # A private project normally just allows the Proprietary policy,506 # A private project normally just allows the Proprietary policy,
512 # even if there is still another policy like Private Security.507 # even if there is still another policy like Private Security.
513 naked_product.information_type = InformationType.PROPRIETARY508 naked_product.information_type = InformationType.PROPRIETARY
514 [prop_policy] = aps.find([(product, InformationType.PROPRIETARY)])509 [prop_policy] = aps.find([(product, InformationType.PROPRIETARY)])
515 self.assertEqual([prop_policy.id], get_aps(naked_product))510 self.assertEqual([prop_policy.id], naked_product.access_policies)
516511
517 # If we switch it back to public, the cache is no longer512 # If we switch it back to public, the cache is no longer
518 # required.513 # required.
519 naked_product.information_type = InformationType.PUBLIC514 naked_product.information_type = InformationType.PUBLIC
520 self.assertIs(None, get_aps(naked_product))515 self.assertIs(None, naked_product.access_policies)
521516
522 # Proprietary projects can have both Proprietary and Embargoed517 # Proprietary projects can have both Proprietary and Embargoed
523 # artifacts, and someone who can see either needs LimitedView on518 # artifacts, and someone who can see either needs LimitedView on
@@ -528,7 +523,7 @@ class TestProduct(TestCaseWithFactory):
528 BugSharingPolicy.EMBARGOED_OR_PROPRIETARY)523 BugSharingPolicy.EMBARGOED_OR_PROPRIETARY)
529 [emb_policy] = aps.find([(product, InformationType.EMBARGOED)])524 [emb_policy] = aps.find([(product, InformationType.EMBARGOED)])
530 self.assertContentEqual(525 self.assertContentEqual(
531 [prop_policy.id, emb_policy.id], get_aps(naked_product))526 [prop_policy.id, emb_policy.id], naked_product.access_policies)
532527
533 def test_checkInformationType_bug_supervisor(self):528 def test_checkInformationType_bug_supervisor(self):
534 # Bug supervisors of proprietary products must not have inclusive529 # Bug supervisors of proprietary products must not have inclusive

Subscribers

People subscribed via source and target branches

to status/vote changes: