def _AllocateIds(self, client):
    """Allocates the next batch of IDs. On success, processes all
    pending waiters. If there are more waiters than ids, re-allocates.
    Otherwise, resets _allocation_pending.
    """
    assert self._cur_id == self._last_id, (self._cur_id, self._last_id)

    def _OnAllocate(result):
      self._last_id = result.return_values[self._next_id_key]
      if self._last_id <= IdAllocator._START_ID:
        self._cur_id = self._last_id
        return self._AllocateIds(client)
      self._cur_id = max(IdAllocator._START_ID, self._last_id - self._allocation)
      assert self._last_id < self._cur_id, 'cur id %d >= allocated last id %d' % \
          (self._cur_id, self._last_id)
      logging.debug("allocated %d %s IDs (%d-%d)" %
                    (self._allocation, self.id_type, self._cur_id, self._last_id))
      if not self._ProcessWaiters():
        self._AllocateIds(client)
      else:
        self._allocation_pending = False

    def _OnError(type, value, traceback):
      logging.error('failed to allocate new id; returning waiters...', exc_info=(type, value, traceback))
      while len(self._waiters):
        self._waiters.popleft()(type, value, traceback)

    self._allocation_pending = True
    with util.MonoBarrier(_OnAllocate, on_exception=_OnError) as b:
      client.UpdateItem(table=self._table.name, key=self.GetKey(),
                        attributes={self._next_id_key:
                                    db_client.UpdateAttr(value=self._allocation, action='ADD')},
                        return_values='UPDATED_NEW', callback=b.Callback())
dataset/ETHPy150Open viewfinderco/viewfinder/backend/db/id_allocator.py/IdAllocator._AllocateIds/swapped operands of `<`