whoops hit reply to author, meant to say: or should I ditch the list of gameIds for each player and instead just query the datastore for all games where game.playerOwnerId == callingPlayerId?
This would avoid that extra call I mentioned where I add the game id to the player's list of joined game ids... Thanks On Jun 19, 1:43 pm, coltsith <[email protected]> wrote: > 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.
