def attempt(self): """ Try to perform this payment. """ self.last_attempted_at = datetime.now() # Write attempted date now so if something happens we can see this # payment was interrupted. self.save() changed_accounts = [] try: flow_graph = FlowGraph(self.payer, self.recipient) flow_links = flow_graph.min_cost_flow(self.amount) with transaction.atomic(using='ripple'): for creditline_id, amount in flow_links: creditline = CreditLine.objects.get(pk=creditline_id) Entry.objects.create_entry(self, creditline.account, -amount * creditline.bal_mult, creditline.limit) changed_accounts.append(creditline.account) self.status = 'completed' self.save() except BaseException as exc: # TODO: Handle collisions better here so we can retry or give the # user an informative error message, rather than the server error page. self.status = 'failed' self.save() if not isinstance(exc, PaymentError): raise # Update cached graphs. for account in changed_accounts: for creditline in (account.pos_creditline, account.neg_creditline): update_creditline_in_cached_graphs(creditline)
def attempt(self): """ Try to perform this payment. """ self.last_attempted_at = datetime.now() # Write attempted date now so if something happens we can see this # payment was interrupted. self.save() changed_accounts = [] try: flow_graph = FlowGraph(self.payer, self.recipient) flow_links = flow_graph.min_cost_flow(self.amount) with transaction.commit_on_success(using="ripple"): for creditline_id, amount in flow_links: creditline = CreditLine.objects.get(pk=creditline_id) Entry.objects.create_entry( self, creditline.account, -amount * creditline.bal_mult, creditline.limit ) changed_accounts.append(creditline.account) self.status = "completed" self.save() except BaseException as exc: # TODO: Handle collisions better here so we can retry or give the # user an informative error message, rather than the server error page. self.status = "failed" self.save() if not isinstance(exc, PaymentError): raise # Update cached graphs. for account in changed_accounts: for creditline in (account.pos_creditline, account.neg_creditline): update_creditline_in_cached_graphs(creditline)
def post_delete(cls, sender, instance, **kwargs): # Delete partner creditline and account itself. instance.account.delete() # Remove from cached flow graph. from cc.payment import flow # TODO: Call from single external process -- not threadsafe! flow.update_creditline_in_cached_graphs(instance)
def post_save(cls, sender, instance, created, **kwargs): if created: # Newly-created creditlines may not have a partner yet, # so updating them will blow up. Update new creditlines # manually. return from cc.payment import flow # TODO: Call from single external process -- not threadsafe! flow.update_creditline_in_cached_graphs(instance)
def post_delete(cls, sender, instance, **kwargs): # Delete partner creditline and account itself. try: instance.account.delete() except Account.DoesNotExist: pass # Remove from cached flow graph. from cc.payment import flow # TODO: Call from single external process -- not threadsafe! # XXX: This is broken - tries to load partner creditline, which # may already be (is?) deleted. flow.update_creditline_in_cached_graphs(instance)
def create_account(self, node1, node2): """ Create account between two nodes. Also creates the required CreditLine records. """ acct = self.create() pos_cl = CreditLine.objects.create(account=acct, node=node1, bal_mult=1) neg_cl = CreditLine.objects.create(account=acct, node=node2, bal_mult=-1) # Manually update new creditlines in cached graphs. from cc.payment import flow flow.update_creditline_in_cached_graphs(pos_cl) flow.update_creditline_in_cached_graphs(neg_cl) return acct
def create_account(self, node1, node2): """ Create account between two nodes. Also creates the required CreditLine records. """ acct = self.create() pos_cl = CreditLine.objects.create( account=acct, node=node1, bal_mult=1) neg_cl = CreditLine.objects.create( account=acct, node=node2, bal_mult=-1) # Manually update new creditlines in cached graphs. from cc.payment import flow flow.update_creditline_in_cached_graphs(pos_cl) flow.update_creditline_in_cached_graphs(neg_cl) return acct