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.