Today we are happy to announce the 1.3.5 release of the App Engine SDK for both Python and Java developers.
Due to popular demand, we have increased the throughput of the Task Queue API, from 50 reqs/sec per app to 50 reqs/sec per queue. You can also now specify the amount of storage available to the taskqueue in your app, for those with very large queues with many millions of tasks. Stay tuned for even more Task Queue scalability improvements in the future.
Additionally, in this release we’ve also added support for precompilation of Python source files to match the same feature we launched for Java last year. For Python, you can now use precompilation to speed up application loading time and to reduce CPU usage for new app instances. You can enable precompilation by including the following lines in your app.yaml file:
This will start offline precompilation of Python modules used by your app when you deploy your application. Currently precompliation is off by default for Python applications, but it will be enabled by default in some future release. (Java precompilation has been enabled by default since the release of 1.3.1.)
To give you a taste of what this feature is like, we tested this on a modified version of Rietveld (which included a copy of Django 1.0.4 in the app directory, and which did not use the datastore in its base url). The latency and CPU usage results for the initial load of the application, after uploading a new version of the app and requesting the homepage, were:
Of course, any individual app’s performance will vary, so we recommend that you experiment with the setting for your application. Please submit your feedback and results to the support group!
In addition to Task Queues and Python precompilation, we have made a few changes to the Blobstore in 1.3.5 We have added file-like interfaces for reading Blobs. In Python, this is supported through the BlobReader class. In Java, we have implemented the BlobstoreInputStream class, which gives an InputStream view of the blobs stored in Blobstore.
More information on this release can be found by reading the release notes for Python and Java.
// Obtain the credentials from your configs credentialObj = new APICredential();credentialObj.setAPIUsername(getServletConfig() .getInitParameter("PPAPIUsername"));credentialObj.setAPIPassword(getServletConfig() .getInitParameter("PPAPIPassword"));credentialObj.setSignature(getServletConfig() .getInitParameter("PPAPISignature"));// setup your AppID from X.comcredentialObj.setAppId(getServletConfig() .getInitParameter("PPAppID"));// setup your Test Business account email // in most cases this would be associated with API CredentialscredentialObj.setAccountEmail(getServletConfig() .getInitParameter("PPAccountEmail"));// add required error condition checks//....
try { // CreateSimplePreapproval request to setup a simple // preapproval with no Payment Period Set CreateSimplePreapproval simplePreapproval = new CreateSimplePreapproval(); // set the API Credentials object (as given in the code above) simplePreapproval.setCredentialObj(credentialObj); // starting date in yyyy-MM-dd format simplePreapproval.setStartingDate("2010-06-25"); // ending date in yyyy-MM-dd format // in this case it's for an year from the starting date simplePreapproval.setEndingDate("2011-06-25"); // set max total amount of all Payments simplePreapproval.setMaxTotalAmountOfAllPayments(52.00); // set max amount for each payment - let's say $1 simplePreapproval.setMaxAmountPerPayment(1.00); // set max number of payments allowed - (52 weeks) simplePreapproval.setMaxNumberOfPayments(52); // set where to send the user in case of a cancellation simplePreapproval.setCancelUrl(req.getRequestURL() + "?action=preapproval&cancel=1"); // set where to return the user after successful approval simplePreapproval.setReturnUrl(req.getRequestURL() + "? return=1&action=preapproval&preapprovalKey=${preapprovalKey}"); /* Set other required fields */ // ... // // set memo for user's transaction history simplePreapproval.setMemo("Preapproval for GAE Sample"); // send the request PreapprovalResponse preapprovalResponse = simplePreapproval.makeRequest(); } catch (//...exceptions go here...//) { // handle exceptions as necessary}
This is a guest post from Jeffrey Rosen, of Wolfire Games.
Recently, Wolfire Games, joined by four other independent video game developers and two charities, put on a pretty unusual promotion: The Humble Indie Bundle. For twelve days, you could have gone to the promotional site and paid what you want (divided any way you choose among the developers, the EFF, and the Child's Play Charity) for a bundle of independent video games, all compatible with Mac, Windows, and Linux.
The reason why I've been invited to write this guest blog post is because the site was built on Google App Engine and, according to Google Analytics, it served about 3.4 million pageviews (1 million unique visitors) in the 12 days it was live. It grossed over $1.2 million. Depending on who you ask, this is quite a lot of traffic, and we exceeded the free App Engine quota. Google sent us a bill for a grand total of $71.56.
I've been a long time advocate of Google App Engine on the Wolfire Blog, even when traffic was tiny, for a number of reasons. I really like its ease of use, and the fact that Google engineers, including Guido himself (the creator of Python), are the ones making sure everything works at 4 AM, and Google's infrastructure is responsible for data durability and security. The pay-as-you-go price combined with a generous free quota is icing.
As an independent video game developer, it's pretty crazy to have these resources at my disposal. While I'm confident in my Python web coding ability, I am definitely not confident in being a Linux sys-admin and commiting to an expensive server that may or may not handle the load properly (especially scary when critical data is involved). This upfront risk and steep learning curve would probably have been the straw that broke the camels back and turned the bundle into vaporware.
According to Google Analytics we did about 3.4 million pageviews (1 million unique visitors) during the bundle period on the Wolfire site (heavily concentrated around the first and last days). The traffic came in huge surges from Reddit, Slashdot, Digg, and a plethora of gaming and tech sites, and people seemed to really enjoy pushing the server by refreshing the page to update the real-time statistics. App Engine performed as advertised: additional servers were seamlessly brought up as needed and shut down when appropriate.
One thing that was really neat about the bundle is that it had a bunch of real-time statistics about purchases along with a leaderboard of the top contributions. There were many interesting donations, for example, $3333.33, $1337, $327.67, and $313.37 and watching the average donation go up and down was really addictive. I think being able to refresh the page to see the sales coming in was a really big draw for the bundle. This feature was really easy to implement on App Engine using a sharding counter. I'm really looking forward to native comet support in App Engine so the next bundle can have this update completely live, without polling or refreshing. Memcache and the datastore is built for stuff like this, so it was very fast.
One awesome thing about App Engine is how it handles the deployment for you transparently and seamlessly. I felt comfortable developing, testing, and ultimately deploying new features to the site, even while it was serving say, 100 visitors per second. App Engine handles all the details of seamlessly bringing down the servers and getting the new ones in place even under intense loads. Because of this, I was able to hack on new features to the site as necessary. For example, I expanded the statistics so that you could see the platform specific average payments in real-time. That feature was started, tested, and deployed on maybe the third day of the bundle. Similarly, I spontaneously added an unplanned sixth game (Samorost 2) to the bundle on the fifth day and deployed minor tweaks dozens of times throughout the promo.
One thing that the bundle made clear to me is that raw Python code is much faster than you might expect. After I finished building the prototype of the bundle, I was getting ready to heavily optimize everything: each hit to the Humble Bundle page executed a few hundred lines of my Python code, doing all sorts of calculations for the statistics and inserting that into a massive Django template. Initially I thought that there would be no way this would be scalable and I'd need to aggressively cache the whole page. However, when I looked at the estimated CPU usage (tip: if you look at the request headers of a page while logged in as an admin, App Engine gives you some estimates on how much it will charge you for 1000 requests and how long it will take) it was something like 0.00375 CPM and was executing in milliseconds. Despite what I had assumed to be inefficient, unoptimized code, the CPM was so ridiculously low and it was executing so fast, I decided not to even bother optimizing the backend further. The only thing that was taking any time at all were the few memcache calls to retrieve the real-time list of tweets, real-time raw sales data, and other interesting stats. In hindsight though, I could have easily shaved off 30 ms by combining all the memcache requests into a single RPC with memcache.get_multi.
While I am really satisfied with App Engine and credit its existence and my familiarity with it for the existence of the Humble Indie Bundle in the first place, there were a few gotchas:
Due to a scheduled maintenance period on the datastore, the bundle was down for about 20 minutes (we need to store metadata about people's orders before we forward them to PayPal, Amazon Payments, or Google Checkout). Normally a message pops up to inform people when downtime occurs is going on, but this didn't activate for some reason, so we had to handle a lot of email about a blank page when people were trying to place their orders. I understand that Google is addressing this though.
The features that I would like to ask for are mostly all "on deck" on the roadmap: SSL for custom domains, comet support, and longer background tasks in particular. I'd also like to see App Engine focus on utilizing Google's infrastructure by serving non-static requests geographically like "web acceleration" services from CDNs. There are some trade-offs due to the nature of the datastore, but I think it can be done.
Thanks for having me on the blog! People can find me on the Wolfire Blog where we talk about more technical and game design topics, and check out our upcoming game Overgrowth.
We have completed the post-mortem on the Datastore outage App Engine experienced two weeks ago on May 25th. We greatly appreciate your patience in this.
A very small percentage of apps (approximately 2%) have been affected by unapplied writes as a result of the outage. “Unapplied writes” are writes that did not get replicated to the secondary Datastore before completing the fail over process. We want to stress that these unapplied writes do not impact the transactional consistency and have not corrupted application data. Instead you can think of them as causing the mirror image between the primary and secondary datastore to be out of sync.
We have emailed administrators of all affected applications to let them know that they should take action. If you do not receive an email, there is no action for you to take. If your application does have unapplied writes, all of the data has been recovered and reinserted into your application’s Datastore as separately labeled entities. We have developed new tools in the Datastore to re-integrate unapplied writes and we have also provided a support email address appengine-unapplied-writes@google.com to help you work one-on-one with the App Engine team as well. For more information on unapplied writes, please see the Unapplied Writes FAQ.
Although this is unrelated to the ongoing Datastore latency issues, we continue to work diligently on a solution for those as well. We expect to have an update early next week on our progress which will be posted on this blog, so please stay tuned.
As many of you know, App Engine’s Datastore performance has been seriously degraded over the last few weeks. In addition to May 25th’s 45 minute Datastore outage, applications have seen an increased latency and thus errors as a result of timeouts. As a rough estimate, we have seen Datastore latency increases of around 2.5x. Comparing April 1st to June 1st on the Status Site shows this trend. These issues in turn have caused problems with other parts of the App Engine service that also rely on the Datastore, such as Task Queues and the Admin Console.
There are a lot of different reasons for the problems over the last few weeks, but at the root of all of them is ultimately growing pains. Our service has grown 25% every two months for the past six months. To accommodate this growth, App Engine has expanded, both increasing our computing footprint and moving between Google datacenters to accommodate our growing size. Although we have moved and expanded, it hasn’t been enough-- and performance has suffered.
We want you to know we are taking the current problems with the Datastore very seriously. We have put other Datastore projects on hold to dedicate more people to accelerating improvements to Datastore performance, and to our datacenter configuration. We expect the Datastore may still have a few issues for the next two weeks, as we respond to the problem. After that point you should begin to see rapid improvements in performance, back to normal levels. Until that point, however, we believe Datastore performance may continue to be at a level that we feel is unacceptable.
So until performance has returned to a state we are proud of, and that you are satisfied with, your applications will not be charged for Datastore CPU costs effective on your May 31st bill. When we are convinced we have returned Datastore performance to a level we consider acceptable, we will give you a 7-day notification on this blog before we begin charging again (Note: Your Datastore CPU budget will still control your app’s CPU usage though you will not be charged for the Datastore CPU. So please don’t turn your budget to $0 during this period).
We hope this gives more clarity into the current issues you’ve seen with your application and we sincerely appreciate your patience as we work through them.
Thank youThe App Engine Team
Update: Clarified which Datastore charges will be disabled
Use promo code NEXT1720 to save $300 off general admission