I’ve read a lot of the GAE articles on counters and this pesky write limit in GAE. I’ve seen solutions with sharding, cron tasks, memcache, etc. Then I learned enough about java threads to be able to ask the question:
Q: Can we implement a counter in servlet threads using concurrency /
servlet static varibales?
This would have the added benefit of fewer writes to the datastore and memcache (cost the same $), and remove the cron requirement as the last servlet in a series of fast counter hits would update the datastore.
I don’t know enough about concurrent programming to come up with a solution, but I imagine something with static servlet variables, maybe “atomic-integers” and a last-update flag to enable checking if THIS servlet was the last servlet to update the static var, in the last 200ms, thus triggering a save to the datastore.
// Servlet gets a hit
// static var counter++
// Checks last datastore save time of the static var, if longer than 200ms
// save to datastore & save "last update time"
// If shorter than 200 ms ago, let the next servlet call update the datastore
Can this be done? Any proposals? Mucho appreciado on your thoughts.
Just to elaborate a bit more on my comment:
As you are probably aware, App Engine spins up a new instance of your app whenever it reaches some traffic threshold. Given that new instances could be spun up on a completely different server, your static counter would be rendered invalid.
Now just to clarify, the correct way of implementing a counter in App Engine would be to use Sharding and split it across multiple entites.
Now assuming you wanted to minimize your datastore calls, you could instead use memcache to store your counter data and write it out to the datastore at a specified frequency (say via cron). Your memcache data will be consistent across all instances of your app.
You of course run the risk of losing your memcache counter in the event memcache goes down, but that’s what writing it out to the datastore takes care of. Again, this isn’t a 100% foolproof solution, sharding is; but it’s one way of minimizing your datastore calls.