There's something warm and comfortable about using Google's App Engine. What began as a fairly radical tool has slowly matured into an asset that's easier to understand and use, if only because the world has adopted many of the ideas.
The basic architectural themes have remained the same. You upload a small kernel of code with your business logic, and App Engine deploys enough instances to satisfy the demand. If you want to store data or synchronise your work between sessions, you have to use Google's proprietary data stores and caching, but everything else feels fairly standard. The first versions of App Engine used Python, but now you can push up Java WAR files filled with JSPs, servlets and server-side logic. The administration is handled through a separate web interface. Command-line issues are pretty much relegated to the past.
I think the biggest challenges for programmers will be adjusting to Google's non-relational data stores. When App Engine first appeared, there weren't so many NoSQL projects around, and the idea of storing collections of name-value pairs was more of a novelty. Anyone approaching App Engine with a bit of experience with NoSQL won't be shocked at all by the simple solution that App Engine forces upon everyone who wants to keep data around. But anyone who still thinks of JOINs and normalised data will need to break from the table-oriented, relational past and adjust to a new way of doing things.
App Engine offers two classes of the data store, so the architect must decide whether to pay for additional power. The basic model makes one data centre the master and all others a slave. If the data centre fails or starts up a scheduled maintenance, your data can't be stored. You must be ready to live with a "planned read-only period". Many modern web applications (think Facebook) can easily survive these kind of glitches, but applications requiring banklike levels of availability and consistency will need to look elsewhere.
The low rent, master-slave configuration is supposed to be about one third the cost of the "high replication" version, with each low rent write costing about five eighths of the high rent equivalent. The low rent version may be twice as slow on writes as the high replication cloud, then again it might not. You have to be careful with some of these numbers because the mechanism includes lots of hidden overhead. Each name-value pair, for instance, includes all the names as overhead because there's no schema. That's the price you pay for the flexibility to store any old thing in any old row.
For some reason, I found myself fretting about the lack of access to the file system. I realise that the idea is to store the bits as blobs so that App Engine can optimize everything, but I still like the ability to write to the file system for some projects.
One of the biggest changes in App Engine is the appearance of economic reality. While Google heavily subsidised the first crop of applications by offering so much for free, it has slowly been squeezing the free apps and pushing people to pay for what they get. Free apps can now access the data store 50,000 times a day, which adds up quickly if you keep more than a few items in the data store.
The new price list includes a long set of quotas and rates. All seem tiny and reasonable, but I have no easy way to compare them. Is 1 cent per 10,000 reads from the data store a good price? Should I hold out for 1 cent per 12,000 reads? Somehow it seems easier to go to the boss and ask for a box with two quad-core processors, a ton of RAM and some fast disks, then cross our fingers. It's not very scientific, but it's so much easier than thinking through all of the details.
One interesting detail is that the App Engine sort of strips away your ability to tune your application's performance to handle peaks: 100 emails will always cost one penny. You can't save money with a cheaper processor and a queue that delays the email.