def __adjustResourcesTrans(self, resource_dict, validate_only): rd = resource_dict.copy() #HACK: shouldn't be more than 25 resource types, but still... playerResources = db.Query(PlayerResources).ancestor(self).fetch(25) #TODO: add transactions around this logic # first add to the resources we know about for pr in playerResources: if not rd.get(pr.resource, None) is None: if pr.amount + rd[pr.resource] < 0: raise db.Rollback() elif not validate_only: pr.amount += rd[pr.resource] pr.put() del rd[pr.resource] # then loop through remaining resources and add them as player resources for r, a in rd.items(): if a < 0: raise db.Rollback() elif not validate_only: logging.info("adjusting %s = %d:" % (r, a)) pr = PlayerResources(parent=self, resource=r, amount=a) pr.put() return True
def increment_counter(key, amount, raiseException): obj = db.get(key) if not obj: raise db.Rollback() obj.counter += amount obj.put() if raiseException: raise db.Rollback()
def query_type_verify(type, value, raiseException): q = db.GqlQuery("SELECT * FROM " + type) if raiseException: raise db.Rollback() for ii in q: if ii.val != value: raise db.Rollback() return True
def increment_counter(key, amount, raiseException): obj = Accumulator.get_by_key_name(key) if not obj: raise db.Rollback() obj.counter += amount obj.put() if raiseException: raise db.Rollback()
def del_object(key, raiseException): if type(key) != type([]): key = [key] for ii in key: obj = db.get(ii) if not obj: raise db.Rollback() obj.delete() if raiseException: raise db.Rollback()
def get_put_verify_delete(key, value, raiseException): obj = get_object(key, raiseException) if not obj: raise db.Rollback() put_object(key, value, raiseException) if type(key) != type([]): key = [key] for ii in key: v = get_value(ii, raiseException) if v != value: raise db.Rollback() del_object(key, raiseException)
def put_object(key, value, raiseException): if type(key) != type([]): key = [key] for ii in key: obj = db.get(ii) if not obj: raise db.Rollback() obj.val = value obj.put() if raiseException: raise db.Rollback()
def pay_allowance(parent_key, child_key, amount): p = Parent(key_name=parent_key, name=parent_key) c = Child(parent=p, key_name=child_key, name=child_key) p = Parent.get(p.key()) if not p: raise db.Rollback() if not c: raise db.Rollback() c = Child.get(c.key()) p.cash -= amount p.put() c.cash += amount c.put()
def tx(): assert db.get(marktwain).name == "Mark Twain" b = Book(parent=marktwain, title="The Adventures Of Tom Sawyer") b.put() raise db.Rollback()
def _tx(): """Use datastore to set slice_start_time to now. If failed for any reason, raise error to retry the task (hence all the previous validation code). The task would die naturally eventually. Returns: True if state commit succeeded. None otherwise. """ fresh_state = model.ShardState.get_by_shard_id(tstate.shard_id) if not fresh_state: logging.error("ShardState missing.") raise db.Rollback() if (fresh_state.active and fresh_state.slice_id == shard_state.slice_id and fresh_state.slice_start_time == shard_state.slice_start_time): fresh_state.slice_start_time = datetime.datetime.now() fresh_state.slice_request_id = os.environ.get("REQUEST_LOG_ID") fresh_state.put(config=config) return True else: logging.warning( "Contention on slice %s-%s execution. Will retry again.", tstate.shard_id, tstate.slice_id) time.sleep(random.randrange(1, 5)) return
def get_value(key, raiseException): logging.info(str(key)) obj = db.get(key) if not obj: raise db.Rollback() logging.info(str(obj)) return obj.val
def query_type(type, raiseException): q = db.GqlQuery("SELECT * FROM " + type) if raiseException: raise db.Rollback() values = [] for ii in q: values.append(ii.val) return values
def query_type_with_value(type, value, raiseException): q = db.GqlQuery("SELECT * FROM " + type + " WHERE val = '" + value + "'") if raiseException: raise db.Rollback() count = 0 for ii in q: count += 1 return count
def UpdateRecord(key, token): item = db.get(key) count = int(memcache.get(token)) item.count += count if count > int(memcache.get(token)): raise db.Rollback() item.put() memcache.decr(token, delta=count)
def get_object(key, raiseException): if type(key) != type([]): key = [key] ret = [] for ii in key: obj = db.get(ii) if not obj: raise db.Rollback() ret.append(obj) return ret
def tx(): fresh_shard_state = db.get( model.ShardState.get_key_by_shard_id(shard_id)) if not fresh_shard_state: raise db.Rollback() if (not fresh_shard_state.active or "worker_active_state_collision" in _TEST_INJECTED_FAULTS): shard_state.active = False logging.error("Spurious task execution. Aborting the shard.") return fresh_shard_state.copy_from(shard_state) fresh_shard_state.put(config=config)
def txn(): target = db.get(target_key) if target: raise db.Rollback() target = Target(key=target_key, destination_email=destination_email, enabled=False, secret=generate_secret()) assign_fields(target) taskqueue.add(method='GET', url='/work/confirm_email', params=dict(target_name=encoded), transactional=True, queue_name='confirm') target.put() return target
def claimJob(self, job_key): """A transaction to claim a job. The transaction is rolled back if the status is not 'waiting'. """ job = Job.get_by_id(job_key) if job.status != 'waiting': raise db.Rollback() job.status = 'started' # pylint: disable-msg=E1103 if job.put(): return job else: return None
def tx(): fresh_shard_state = db.get( model.ShardState.get_key_by_shard_id(shard_id)) if not fresh_shard_state: raise db.Rollback() if (not fresh_shard_state.active or "worker_active_state_collision" in _TEST_INJECTED_FAULTS): logging.error( "Shard %s is not active. Possible spurious task " "execution. Dropping this task.", shard_id) logging.error("Datastore's %s", str(fresh_shard_state)) logging.error("Slice's %s", str(shard_state)) return fresh_shard_state.copy_from(shard_state) fresh_shard_state.put(config=config) if retry_shard: self._schedule_slice(fresh_shard_state, tstate) elif shard_state.active: self.reschedule(fresh_shard_state, tstate)
def _tx(): fresh_shard_state = model.ShardState.get_by_shard_id( tstate.shard_id) if not fresh_shard_state: raise db.Rollback() if (not fresh_shard_state.active or "worker_active_state_collision" in _TEST_INJECTED_FAULTS): logging.error( "Shard %s is not active. Possible spurious task " "execution. Dropping this task.", tstate.shard_id) logging.error("Datastore's %s", str(fresh_shard_state)) logging.error("Slice's %s", str(shard_state)) return fresh_shard_state.copy_from(shard_state) if fresh_shard_state.active: assert task is not None self._add_task(task, fresh_shard_state, spec, queue_name) fresh_shard_state.put(config=config)
def txn(id): key_name = cls.get_key_name(id) if additional_tq_url is not None: tq_kwargs.update( {'session_key': db.Key.from_path(cls.kind(), key_name)}) taskqueue.add(url=url_for(additional_tq_url, **tq_kwargs), transactional=True) taskqueue.add(url=url_for("_internal/expire_temporary_session", session_key=db.Key.from_path( cls.kind(), key_name)), countdown=countdown, transactional=True) session = cls.get_by_key_name(key_name) if session is None: if data: session = cls(key_name=key_name, user=user, data=data) else: session = cls(key_name=key_name, user=user) session.put() return session else: raise db.Rollback("The specified id already exists.")
def txn(): modified_target = db.get(target.key()) if not modified_target: db.Rollback() assign_fields(modified_target) modified_target.put()