class Account(object): def __init__(self, balance=10): self.account_info = Store() curr_balance = self.account_info.checkout("balance") curr_balance.set(balance) curr_balance.commit() @retry # Retries until transaction succeeds def deposit(self, amount): curr_balance = self.account_info.checkout("balance") new_balance = curr_balance.value + amount curr_balance.set(new_balance) curr_balance.commit() return new_balance @retry(timeout=0.005) # Timeout after 5 milliseconds (Are we really that worried?) def withdraw(self, amount): curr_balance = self.account_info.checkout("balance") if curr_balance.value < amount: raise InsufficientFunds("Insufficient Funds in your account", requested=amount, balance=curr_balance.value) new_balance = curr_balance.value - amount curr_balance.set(new_balance) curr_balance.commit() return amount @property def balance(self): curr_balance = self.account_info.checkout("balance") return curr_balance.value
class Account(object): def __init__(self, balance=10): self.account_info = Store() curr_balance = self.account_info.checkout("balance") curr_balance.set(balance) curr_balance.commit() @retry # Retries until transaction succeeds def deposit(self, amount): curr_balance = self.account_info.checkout("balance") new_balance = curr_balance.value + amount curr_balance.set(new_balance) curr_balance.commit() return new_balance @retry(timeout=0.005 ) # Timeout after 5 milliseconds (Are we really that worried?) def withdraw(self, amount): curr_balance = self.account_info.checkout("balance") if curr_balance.value < amount: raise InsufficientFunds("Insufficient Funds in your account", requested=amount, balance=curr_balance.value) new_balance = curr_balance.value - amount curr_balance.set(new_balance) curr_balance.commit() return amount @property def balance(self): curr_balance = self.account_info.checkout("balance") return curr_balance.value
class Account(object): def __init__(self, balance=10): self.account_info = Store() curr_balance = self.account_info.checkout("balance") curr_balance.set(balance) curr_balance.commit() @retry # Retries until transaction succeeds def deposit(self, amount): curr_balance = self.account_info.checkout("balance") new_balance = curr_balance.value + amount curr_balance.set(new_balance) curr_balance.commit() return new_balance @retry(max_tries=50) # Retries up to 50 times def withdraw(self, amount): curr_balance = self.account_info.checkout("balance") if curr_balance.value < amount: raise InsufficientFunds("Insufficient Funds in your account", requested=amount, balance=curr_balance.value) new_balance = curr_balance.value - amount curr_balance.set(new_balance) curr_balance.commit() return amount @property def balance(self): curr_balance = self.account_info.checkout("balance") return curr_balance.value
class Account2(object): def __init__(self, balance=10): self.account_info = Store() curr_balance = self.account_info.checkout("balance") curr_balance.set(balance) curr_balance.commit() @retry # Retries until transaction succeeds def deposit(self, amount): curr_balance = self.account_info.checkout("balance") new_balance = curr_balance.value + amount curr_balance.set(new_balance) curr_balance.commit() return new_balance # @retry(max_tries=100) # Try up to 100 times - maybe should be a timeout? @retry(timeout=0.004) # Timeout after 5 milliseconds (Are we really that worried?) def withdraw(self, amount): curr_balance = self.account_info.checkout("balance") print "ATTEMPT WITHDRAW", amount, self, curr_balance if curr_balance.value < amount: raise InsufficientFunds("Insufficient Funds in your account", requested=amount, balance=curr_balance.value) new_balance = curr_balance.value - amount curr_balance.set(new_balance) curr_balance.commit() print "WITHDRAW SUCCESS", amount, self, curr_balance return amount @property def balance(self): curr_balance = self.account_info.checkout("balance") return curr_balance.value
class Account(object): """This is the 'traditional' approach of interacting with the STM module It's here as a bare example, but lends itself to other ideas/approaches. One of those other approaches is described in Account2 """ def __init__(self, balance=10): self.account_info = Store() curr_balance = self.account_info.checkout("balance") curr_balance.set(balance) curr_balance.commit() def deposit(self, amount): deposited = False while not deposited: try: curr_balance = self.account_info.checkout("balance") new_balance = curr_balance.value + amount curr_balance.set(new_balance) curr_balance.commit() deposited = True except ConcurrentUpdate: pass except BusyRetry: pass return new_balance def withdraw(self, amount): withdrawn = False while not withdrawn: try: curr_balance = self.account_info.checkout("balance") if curr_balance.value < amount: raise InsufficientFunds( "Insufficient Funds in your account", requested=amount, balance=curr_balance.value) new_balance = curr_balance.value - amount curr_balance.set(new_balance) curr_balance.commit() withdrawn = True except ConcurrentUpdate: pass except BusyRetry: pass return amount @property def balance(self): curr_balance = self.account_info.checkout("balance") return curr_balance.value
class Sprite(Actor): def __init__(self): super(Sprite, self).__init__() self.sprite_state = Store() self.update_pos(400,300) self.pos = self.get_pos() print self.pos def get_pos(self, force=False): if (time.time() < self.sprite_state.last_update) or force: self.pos = self.sprite_state.export(["x", "y"]) return self.pos # Threadsafe update of shareable state @retry def update_pos(self, x, y): repo = self.sprite_state.checkout() with repo.changeset("x","y") as c: # This can fail c["x"].set(x) c["y"].set(y) self.pos = self.get_pos(force=True) def render(self, surface, absolute=True): # Assume screen co-ordinates pass
class Sprite(Actor): def __init__(self): super(Sprite, self).__init__() self.sprite_state = Store() self.update_pos(400, 300) self.pos = self.get_pos() print self.pos def get_pos(self, force=False): if (time.time() < self.sprite_state.last_update) or force: self.pos = self.sprite_state.export(["x", "y"]) return self.pos # Threadsafe update of shareable state @retry def update_pos(self, x, y): repo = self.sprite_state.checkout() with repo.changeset("x", "y") as c: # This can fail c["x"].set(x) c["y"].set(y) self.pos = self.get_pos(force=True) def render(self, surface, absolute=True): # Assume screen co-ordinates pass
class Account2(object): def __init__(self, balance=10): self.account_info = Store() curr_balance = self.account_info.checkout("balance") curr_balance.set(balance) curr_balance.commit() @retry # Retries until transaction succeeds def deposit(self, amount): curr_balance = self.account_info.checkout("balance") new_balance = curr_balance.value + amount curr_balance.set(new_balance) curr_balance.commit() return new_balance # @retry(max_tries=100) # Try up to 100 times - maybe should be a timeout? @retry(timeout=0.004 ) # Timeout after 5 milliseconds (Are we really that worried?) def withdraw(self, amount): curr_balance = self.account_info.checkout("balance") print "ATTEMPT WITHDRAW", amount, self, curr_balance if curr_balance.value < amount: raise InsufficientFunds("Insufficient Funds in your account", requested=amount, balance=curr_balance.value) new_balance = curr_balance.value - amount curr_balance.set(new_balance) curr_balance.commit() print "WITHDRAW SUCCESS", amount, self, curr_balance return amount @property def balance(self): curr_balance = self.account_info.checkout("balance") return curr_balance.value