When you say "higher in frequency" what do you mean? How many queries per second? How many games total will be active in your system at once?
Keep in mind that your query will be eventually consistent. When someone joins a game, that fact will not become visible to the queries right away - often for seconds. But your query is by nature "eventual" since someone could have joined the game immediately after the query was run, so presumably you already handle this case. One immediate improvement is to convert to your regular query to a keys-only query followed by a batch fetch. If you have caching, you only pay for the keys-only results (1/7th the cost). I see you're using Java; if you use Objectify4 this is automatically done for you with the @Cache annotation and "hybrid" queries (the default with @Cache entities). The next step is to cache the keys-only query itself in memcache for a limited amount of time. It would be nice to expire it explicitly when you know it changes - which is only when a game is created or a game fills up (not for simple add or leave game). The problem is, there's no guarantee that the subsequent query (which will populate the cache) does not contain stale eventual data. I can't think of a way around this other than just making sure the expiry period is short so it gets refreshed; you're just trying to reduce the query count, not eliminate it. You can't query by playerNames.size() but you can store an indexed field numPlayers in the entity. There's no selecting of specific fields out for an entity (with the exception of Projection queries, which are very limited and probably not what you are after) so you can't get everything-but-gameState. This probably won't affect price (a read op is a read op no matter the size of the entity) but it could affect latency (more RPCs to get the same bit of data). The usual solution is simply to put the gameState blob into separate entity with the same id. Jeff On Thu, Aug 23, 2012 at 6:37 PM, Mark <[email protected]> wrote: > Hi, > > I'm trying to see if it's feasible to write a game using app engine as the > backend. > > The task I'm most worried about is the discoverability of games. A user can > create a new game (which creates a Game object in the datastore). Then other > users can hit an endpoint to get a listing of open games, sorted by creation > date. > > Creating a new game will be a very low frequency operation, so no worries > there. Users polling for new open games will be much higher in frequency > though. Each time a user requests a listing of games, I need to go fetch a > page of Game objects from the datastore. Let's say a page size = 20. And the > Game object looks like this: > > class Game { > String name; > long timestampCreated; > long timestampStarted; > String mapName; > String hostUsername; > int numPlayersMax; > List<String> playerNames; // usernames of other players currently > joined > Text gameState; // game state as serialized json string > } > > the query would be something like: > > select Games where timestampStarted = 0 > and playerNames.size() < numPlayersMax > order by timestampCreated DESC limit 20; > > First, I'm hoping it's possible to avoid loading the Text field in this > listings query since it's not needed for rendering yet. Still there would be > a fair number of fields to fetch and deserialize, and I'm afraid my costs > would quickly make it impractical. > > I could try keeping a list of open games in memcache, but not sure if I > could achieve consistency between the memcache state and the datastore state > of games. Will be looking into that. > > I've got a very similar game to this already published, using a single jetty > instance + mysql on one machine. It's starting to get too much traffic now, > and scaling would be a pain. App engine's scalability looks great for > something like this, but not sure if the # of writes and inefficient reads I > need to perform are a good idea. > > Any general thoughts on this would be greatly appreciated. I'm starting to > dig into this now and any thoughts on how you'd implement the above would be > great. In my already-published game (mentioned above), I ran a dark test > where I'd call through to a (quickly implemented) mirror of the game running > on app engine. It quickly ate through the daily quota! > > Thanks > > -- > You received this message because you are subscribed to the Google Groups > "Google App Engine" group. > To view this discussion on the web visit > https://groups.google.com/d/msg/google-appengine/-/cvpOxGrMRaoJ. > 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. -- 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.
