Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Commit

Permalink
update receiving amounts of members when changing team takes
Browse files Browse the repository at this point in the history
  • Loading branch information
Changaco committed Jun 14, 2014
1 parent b7aa3d1 commit 2b9eea3
Showing 1 changed file with 37 additions and 17 deletions.
54 changes: 37 additions & 17 deletions gittip/models/_mixin_team.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,23 +127,43 @@ def set_take_for(self, member, take, recorder):
def __set_take_for(self, member, amount, recorder):
assert self.IS_PLURAL
# XXX Factored out for testing purposes only! :O Use .set_take_for.
self.db.run("""
INSERT INTO takes (ctime, member, team, amount, recorder)
VALUES ( COALESCE (( SELECT ctime
FROM takes
WHERE member=%(member)s
AND team=%(team)s
LIMIT 1
), CURRENT_TIMESTAMP)
, %(member)s
, %(team)s
, %(amount)s
, %(recorder)s
)
""", dict(member=member.username, team=self.username, amount=amount,
recorder=recorder.username))
with self.db.get_cursor() as cursor:
# Lock to avoid race conditions
cursor.run("LOCK TABLE takes IN EXCLUSIVE MODE")

This comment has been minimized.

Copy link
@chadwhitacre

chadwhitacre Jun 16, 2014

Contributor

First time we've used this, yeah? What are the implications? What can and can't be done by other users while this lock is held?

This comment has been minimized.

Copy link
@chadwhitacre

chadwhitacre Jun 16, 2014

Contributor

Also, how is the lock release? When the transaction is committed/rolled back?

This comment has been minimized.

This comment has been minimized.

Copy link
@Changaco

Changaco Jun 16, 2014

Author Contributor

@whit537 The lock blocks: any other transaction that tries to do acquire that same lock, and also concurrent writes. It still allows read access for everything else though, so it won't block the whole site. The lock is released at the end of the transaction.

# Compute the current takes
old_takes = self.compute_actual_takes(cursor)
# Insert the new take
cursor.run("""
INSERT INTO takes (ctime, member, team, amount, recorder)
VALUES ( COALESCE (( SELECT ctime
FROM takes
WHERE member=%(member)s
AND team=%(team)s
LIMIT 1
), CURRENT_TIMESTAMP)
, %(member)s
, %(team)s
, %(amount)s
, %(recorder)s
)
""", dict(member=member.username, team=self.username, amount=amount,
recorder=recorder.username))
# Compute the new takes
new_takes = self.compute_actual_takes(cursor)
# Update receiving amounts in the participants table
for username in set(old_takes.keys()).union(new_takes.keys()):
old = old_takes.get(username, {}).get('actual_amount', Decimal(0))
new = new_takes.get(username, {}).get('actual_amount', Decimal(0))
diff = new - old
if diff != 0:
cursor.run("""
UPDATE participants
SET takes = (takes + %(diff)s)
, receiving = (receiving + %(diff)s)
WHERE username=%(username)s
""", dict(username=username, diff=diff))

def get_takes(self, for_payday=False, cursor=None):
"""Return a list of member takes for a team.
Expand Down

2 comments on commit 2b9eea3

@chadwhitacre
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IRC

@chadwhitacre
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with this commit.

Please sign in to comment.