Hey this is really helpful! I use java but I think I can translate the
code.

Btw though, each player has a list of gameIds that they're part of.
How do I modify that player's list of gameIds, since I can't do that
in the transaction. (But If I do it outside the transaction there runs
the risk of it becoming unsynchronized. Would this work:

bool joinedGame = false;

transaction start
    try to join game
    if success then joinedGame = true
    else break
transaction end

if joinedGame then add gameId to player.gameIds



On Jun 17, 10:39 am, Blixt <[email protected]> wrote:
> I think you should ignore the "available games in list" case entirely.
> It doesn't matter if your datastore lists the game as available even
> if it's not for 100ms. It'll still be less time than it takes for
> player B to get a response just before player A joined and respond to
> it anyways, so you can't avoid cases where player B gets "The game has
> already been filled". So just make the game unavailable separately.
>
> However, for joining a game you should use transactions. Here's how I
> would do it (using Python):
> def join_game(game_id, player_id):
>     # Fetch game in transaction. If you fetch the game outside a
> transaction,
>     # you can't know for sure what its state in the datastore is.
>     game = Game.get_by_id(game_id)
>     # This function presumably checks the number of participants, and
> maybe
>     # some other things. Preferably, it shouldn't do any datastore
> lookups. If
>     # it does, they must be on entities in the same entity group as
> the game.
>     if not game.player_can_join(player_id):
>         # This exception will automatically roll back the transaction.
> In this
>         # case, no changes were made before the exception, but it's
> good to
>         # know. :)
>         raise GameNotAvailableError('Sorry, that game is not
> available.')
>     # Increment the number of participants (this value could be used
> to check
>     # if the game has been filled.
>     game.participants += 1
>     # You could also store a list of player ids/names in the game.
>     game.players.append(player_id)
>     game.put()
>
> # Run the above in a transaction.
> db.run_in_transaction(join_game, game_id, player_id)
>
> On Jun 15, 4:48 pm, coltsith <[email protected]> wrote:
>
>
>
> > Hi, I'm writing a simple game server where players can create games
> > and browse games. I've come across the following dilemma though and
> > want to see if my solution is a good idea. The dilemma:
>
> > User A calls joinGameAndRemoveItFromList().
>
> > User B calls fetchAvailableGamesInList() at the same time.
>
> > I'm concerned that User B may fetch the game that User A is joining
> > and removing from list (since it's no longer available)
>
> > My solution would be to lock the game list while User A is making his
> > call. That way User B would wait until User A is done with the list.
>
> > However, I realize that this could be very slow. Say there's thousands
> > of players all wanting to browse the available games (hey it could
> > happen!) and they shouldn't all have to wait for A to finish,
> > especially if A is slow for some reason.
>
> > Does anyone have any advice on if this is the right way to go, or if
> > there's a better solution?
>
> > Thanks!

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en.

Reply via email to