Repository: gratipay/gratipay.com

Issue:
Cannot close (delete) my account
I works for a while but then I see an "Application Error" page from Heroku. Ostensibly the operation takes too long and Heroku kills the request.

Cannot close (delete) my account
I works for a while but then I see an "Application Error" page from Heroku. Ostensibly the operation takes too long and Heroku kills the request.



Discussion:
@sigmavirus24 - When did you try this?

I have successfully reproduced the deadlock locally. The account closing logic is choking on @sigmavirus24 still being part of a team.

@rohitpaulk I tried it twice, about 5 minutes in between each try. The last attempt was a minute before I filed the issue. @Changaco I didn't realize I was part of a team. How do I leave?

@sigmavirus24 Drop your take on https://gratipay.com/Gratipay/members/ to zero.

@whit537 done. Thanks. I don't know when my take was every > 0. I don't remember setting that. This should probably stay open given the fact that team members can't cancel their account but my problem is effectively solved. Thanks all!

@sigmavirus24 Cool. Best wishes. :-)

+1 from @kyzh via [Twitter](https://twitter.com/kyzh_ebooks/status/550668556825010178).

@sigmavirus24 - When did you try this?

I have successfully reproduced the deadlock locally. The account closing logic is choking on @sigmavirus24 still being part of a team.

@rohitpaulk I tried it twice, about 5 minutes in between each try. The last attempt was a minute before I filed the issue. @Changaco I didn't realize I was part of a team. How do I leave?

@sigmavirus24 Drop your take on https://gratipay.com/Gratipay/members/ to zero.

@whit537 done. Thanks. I don't know when my take was every > 0. I don't remember setting that. This should probably stay open given the fact that team members can't cancel their account but my problem is effectively solved. Thanks all!

@sigmavirus24 Cool. Best wishes. :-)

+1 from @kyzh via [Twitter](https://twitter.com/kyzh_ebooks/status/550668556825010178).


Resolving patch:
diff --git a/gratipay/models/_mixin_team.py b/gratipay/models/_mixin_team.py
--- a/gratipay/models/_mixin_team.py
+++ b/gratipay/models/_mixin_team.py
@@ -172,7 +172,7 @@ def update_taking(self, old_takes, new_takes, cursor=None, member=None):
             new = new_takes.get(username, {}).get('actual_amount', Decimal(0))
             diff = new - old
             if diff != 0:
-                r = (self.db or cursor).one("""
+                r = (cursor or self.db).one("""
                     UPDATE participants
                        SET taking = (taking + %(diff)s)
                          , receiving = (receiving + %(diff)s)


Test patch:
diff --git a/tests/py/test_close.py b/tests/py/test_close.py
--- a/tests/py/test_close.py
+++ b/tests/py/test_close.py
@@ -19,6 +19,7 @@ class TestClosing(Harness):
     # close
 
     def test_close_closes(self):
+        team = self.make_participant('team', claimed_time='now', number='plural', balance=50)
         alice = self.make_participant('alice', claimed_time='now', balance=D('10.00'))
         bob = self.make_participant('bob', claimed_time='now')
         carl = self.make_participant('carl', claimed_time='now')
@@ -26,10 +27,15 @@ def test_close_closes(self):
         alice.set_tip_to(bob, D('3.00'))
         carl.set_tip_to(alice, D('2.00'))
 
+        team.add_member(alice)
+        team.add_member(bob)
+        assert len(team.get_current_takes()) == 2  # sanity check
+
         alice.close('downstream')
 
         assert carl.get_tip_to('alice')['amount'] == 0
         assert alice.balance == 0
+        assert len(team.get_current_takes()) == 1
 
     def test_close_raises_for_unknown_disbursement_strategy(self):
         alice = self.make_participant('alice', balance=D('0.00'))
@@ -334,20 +340,6 @@ def test_cpi_clears_communities(self):
 
         assert Community.from_slug('test').nmembers == 1
 
-    def test_cpi_clears_teams(self):
-        team = self.make_participant('team', number='plural')
-        alice = self.make_participant('alice', claimed_time='now')
-        team.add_member(alice)
-        bob = self.make_participant('bob', claimed_time='now')
-        team.add_member(bob)
-
-        assert len(team.get_current_takes()) == 2  # sanity check
-
-        with self.db.get_cursor() as cursor:
-            alice.clear_personal_information(cursor)
-
-        assert len(team.get_current_takes()) == 1
-
 
     # uic = update_is_closed