Commit 65e3a418 authored by Giorgos Korfiatis's avatar Giorgos Korfiatis

astakos: Revert bulk update of holdings in commissions

db464c6f introduced a bug: deleting holdings (and then bulk creating them)
interferes with locking; a thread that waits for holdings will not get
the deleted ones.

Revert to separate updating of holdings when issuing and resolving
commissions.
parent f480a496
...@@ -136,13 +136,11 @@ def issue_commission(clientkey, provisions, name="", force=False): ...@@ -136,13 +136,11 @@ def issue_commission(clientkey, provisions, name="", force=False):
provisions = _merge_same_keys(provisions) provisions = _merge_same_keys(provisions)
keys = [key for (key, value) in provisions] keys = [key for (key, value) in provisions]
holdings = _get_holdings_for_update(keys) holdings = _get_holdings_for_update(keys)
changed_holdings = {}
try: try:
for key, quantity in provisions: for key, quantity in provisions:
# Target # Target
try: try:
th = holdings[key] th = holdings[key]
changed_holdings[th.id] = th
except KeyError: except KeyError:
m = ("There is no such holding %s" % unicode(key)) m = ("There is no such holding %s" % unicode(key))
provision = _mkProvision(key, quantity) provision = _mkProvision(key, quantity)
...@@ -159,10 +157,9 @@ def issue_commission(clientkey, provisions, name="", force=False): ...@@ -159,10 +157,9 @@ def issue_commission(clientkey, provisions, name="", force=False):
holdings[key] = th holdings[key] = th
provisions_to_create.append((key, quantity)) provisions_to_create.append((key, quantity))
except QuotaholderError: except QuotaholderError:
operations.revert()
raise raise
Holding.objects.filter(id__in=changed_holdings.keys()).delete()
Holding.objects.bulk_create(changed_holdings.values())
commission = Commission.objects.create(clientkey=clientkey, commission = Commission.objects.create(clientkey=clientkey,
name=name, name=name,
issue_datetime=datetime.now()) issue_datetime=datetime.now())
...@@ -256,7 +253,6 @@ def resolve_pending_commissions(clientkey, accept_set=None, reject_set=None, ...@@ -256,7 +253,6 @@ def resolve_pending_commissions(clientkey, accept_set=None, reject_set=None,
accepted.append(serial) if accept else rejected.append(serial) accepted.append(serial) if accept else rejected.append(serial)
ps = provisions.get(serial, []) ps = provisions.get(serial, [])
changed_holdings = {}
provision_ids = [] provision_ids = []
plog = [] plog = []
for pv in ps: for pv in ps:
...@@ -265,8 +261,6 @@ def resolve_pending_commissions(clientkey, accept_set=None, reject_set=None, ...@@ -265,8 +261,6 @@ def resolve_pending_commissions(clientkey, accept_set=None, reject_set=None,
if h is None: if h is None:
raise CorruptedError("Corrupted provision '%s'" % key) raise CorruptedError("Corrupted provision '%s'" % key)
changed_holdings[h.id] = h
provision_ids.append(pv.id) provision_ids.append(pv.id)
quantity = pv.quantity quantity = pv.quantity
action = finalize if accept else undo action = finalize if accept else undo
...@@ -279,8 +273,6 @@ def resolve_pending_commissions(clientkey, accept_set=None, reject_set=None, ...@@ -279,8 +273,6 @@ def resolve_pending_commissions(clientkey, accept_set=None, reject_set=None,
comm_reason = prefix + reason[-121:] comm_reason = prefix + reason[-121:]
plog.append( plog.append(
_log_provision(commission, pv, h, log_datetime, comm_reason)) _log_provision(commission, pv, h, log_datetime, comm_reason))
Holding.objects.filter(id__in=changed_holdings.keys()).delete()
Holding.objects.bulk_create(changed_holdings.values())
Provision.objects.filter(id__in=provision_ids).delete() Provision.objects.filter(id__in=provision_ids).delete()
ProvisionLog.objects.bulk_create(plog) ProvisionLog.objects.bulk_create(plog)
commission.delete() commission.delete()
......
...@@ -77,10 +77,12 @@ class Import(Operation): ...@@ -77,10 +77,12 @@ class Import(Operation):
usage=usage_max) usage=usage_max)
holding.usage_max = new_usage_max holding.usage_max = new_usage_max
holding.save()
@classmethod @classmethod
def _finalize(cls, holding, quantity): def _finalize(cls, holding, quantity):
holding.usage_min += quantity holding.usage_min += quantity
holding.save()
class Release(Operation): class Release(Operation):
...@@ -102,10 +104,12 @@ class Release(Operation): ...@@ -102,10 +104,12 @@ class Release(Operation):
usage=usage_min) usage=usage_min)
holding.usage_min = new_usage_min holding.usage_min = new_usage_min
holding.save()
@classmethod @classmethod
def _finalize(cls, holding, quantity): def _finalize(cls, holding, quantity):
holding.usage_max -= quantity holding.usage_max -= quantity
holding.save()
class Operations(object): class Operations(object):
......
...@@ -138,6 +138,7 @@ class QuotaholderTest(TestCase): ...@@ -138,6 +138,7 @@ class QuotaholderTest(TestCase):
r = qh.get_pending_commissions(clientkey=self.client) r = qh.get_pending_commissions(clientkey=self.client)
self.assertEqual(len(r), 1) self.assertEqual(len(r), 1)
serial = r[0] serial = r[0]
self.assertEqual(serial, s1)
r = qh.resolve_pending_commission(self.client, serial) r = qh.resolve_pending_commission(self.client, serial)
self.assertEqual(r, True) self.assertEqual(r, True)
r = qh.get_pending_commissions(clientkey=self.client) r = qh.get_pending_commissions(clientkey=self.client)
...@@ -151,6 +152,13 @@ class QuotaholderTest(TestCase): ...@@ -151,6 +152,13 @@ class QuotaholderTest(TestCase):
} }
self.assertEqual(r, quotas) self.assertEqual(r, quotas)
logs = models.ProvisionLog.objects.filter(serial=serial)
self.assertEqual(len(logs), 2)
log1 = filter(lambda p: p.resource == resource1
and p.delta_quantity == limit1/2
and p.usage_min == limit1/2, logs)
self.assertEqual(len(log1), 1)
# resolve commissions # resolve commissions
serial = self.issue_commission([((holder, source, resource1), 1), serial = self.issue_commission([((holder, source, resource1), 1),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment