GAE: Data Warehouse Consistency, Avoiding Competition (i.e. No Person Groups)

I am creating a voting site in GAE that will work as follows:

  • Voting is declared open (but remains open only for a minute or two).
  • People cast their votes.
  • Voting is closed. No more votes can be cast.
  • Results are displayed.

The voting phase lasts a minute or two, so many votes will be cast in a short period of time.

I want to avoid disputes in Datastore, so I can’t store voices in a group of entities (this will most likely exceed the limit of 1 record / sec).

However, I must ensure that I count ALL the votes as soon as the voting is closed.

My question is: how can I ensure Datastore consistency for votes (without a group of individuals) after the close of the vote? In other words, at what point can I be sure that every vote was written (and readable) in the data warehouse?

Only once, when I know that every vote is readable, can I correctly calculate the results.

PS: I should note that this is not a “simple” voting scheme; voters choose their 1st, 2nd and 3rd options, and the winner is determined by a rather complicated iterative process, i.e. not enough to count the number of votes coming from each candidate.

Thanks in advance!

+4
source share
2 answers

My 2c.

, . choice . , . user_id , .

3 . ? .

2.

1 - ( )

class VoteHandler(webapp2.RequestHandler):

  def get(self, choice):

    user = users.get_current_user()

    # Blind write it! or just check before if exists 
    Vote(id=user.user_id, selection=choice).put()

. , , . . , , , . , . , .

2 - Get_or_inserts ( )

class VoteHandler(webapp2.RequestHandler):

  def get(self, choice):

    user = users.get_current_user()

    # Construct a vote with the user_id as a key using get_or_insert
    vote = Vote.get_or_insert(user.user_id())

    # Check if he has voted (general check with default entity prop to None)
    if vote.selection is not None:
      # vote is cast return or do other logic
      return

    vote.selection = choice
    vote.put()

, user_id, , . , , .

get_or_insert, :

def txn(key_name, **kwds):
  entity = Story.get_by_key_name(key_name, parent=kwds.get('parent'))
  if entity is None:
    entity = Story(key_name=key_name, **kwds)
    entity.put()
  return entity

def get_or_insert(key_name, **kwargs):
  return db.run_in_transaction(txn, key_name, **kwargs)

get_or_insert('some key', title="The Three Little Pigs")

get_or_insert , , "". . !!! vote_selection .

:

user_id, , .

, 2 , , :

  • , .
  • .
  • .

, , None, . . ( ).

3 -

class VoteHandler(webapp2.RequestHandler):

  def get(self, choice):

    user = users.get_current_user()

    self.vote(user.user_id, choice)

  @ndb.transactional()
  def vote(key, choice):
    vote = ndb.Key(Vote, key).get()
      if vote:
         # user has voted 
         return
      # return the key 
      return Vote(id=key, selection=choise).put()

, . , .

, //.

+2
+2

Source: https://habr.com/ru/post/1529025/


All Articles