Google App Engine Launched!

If you’ve talked to me about work during the last couple years, I’ve probably downplayed it, resorted to generalities, or just changed the subject. No longer! We’ve finally taken the wraps off our project, Google App Engine. From the docs:

Google App Engine lets you run your web applications on Google’s infrastructure. App Engine applications are easy to build, easy to maintain, and easy to scale as your traffic and data storage needs grow. With App Engine, there are no servers to maintain: You just upload your application, and it’s ready to serve your users.

Personally, I spent most of my time writing the datastore, both the backend and much of the Python API. When I found extra time, though, I had a lot of fun writing apps and libraries on top of App Engine. I particularly enjoyed writing an interactive shell, an OpenID provider, and a full text search library.

We’ve been excited about the project since the beginning, and we can’t wait to see what people do with it. If you’re a developer and you have some spare time, please try it out and let us know what you think!


25 thoughts on “Google App Engine Launched!

  1. Ryan, you’ve single-handedly turned every gmail account into an OpenID!

    Good work :)

    Lets see how long it takes for people to pick up on that :)

  2. the OpenID provider doesn’t work, after the Google sign in, the redirect fails

  3. yeah, it is unhappy in production. i’ll try to investigate when i come across some free time. more when i know it…

  4. ryan, think it’s okay if websites start putting a little Google helper button next to their openid_url inputs that point to your OpenID provider app?

  5. hmm…sorry, but no, i don’t think so. it’s just a sample app for App Engine; it’s definitely not a full-fledged, official Google product.

  6. I am trying to create a service to allow registered voters to participate in legislature through the internet. I am using GovTrack.us’s work to track legislation and keep voters up to date, but I would like to enable registered voters to create, support, and influence their legislator’s ultimate decisions. In order to do this, I need confidence that each user is in fact the registered voter they claim to be. I have a solution to do this on a local level, but I would like to do this nationally. If you have any ideas, please let me know. My email is on my website.

  7. Yeah, the redirect after successful auth doesn’t work for any of the sites I tried

  8. re: comment 1,

    Wonder how quickly you’ll run out of your 5m page views — this will be awesome!

  9. It is a neat application, but is not working unfortunately at Blogger.com. Hope you can fix it. Thanks.

  10. Great work!

    A question re. OpenID provider and delegation: the provider gives me just one URL. When trying to set up OpenID delegation on my website, I entered this URL into “link rel=’openid.server'”. What value should I use for “rel=openid.delegate'”?

  11. I stepped across this Blog while looking around for info on how to build an OpenID provider for Google App Engine…. Go figure :)

    Is the source code for your Google App Engine Open ID provider available?

  12. Ryan, congrats! I knew you were up to something when you mentioned who you were working with. Got your invite and I’m looking forward to spending some time poking around what you guys have put out there.

    Hope all is well, take care!

  13. ryan, i just watched your google IO presentation.. @ 1/4 way through i could give your presentation just with a different verbiage. (AND STOPPED IT 1/2 WAY THROUGH… 2 WRITE THIS..)
    when you can database ‘a’ with a kind/type globally your ON! :)
    i ‘db designer/programmer’ all my databases 7th form (i’m a geek!.. so what?) perfectionist yes! even with my schema results would even be less on your presentation ‘on a call’ and i’m sure it really is, in actuality(that was just 4 presentation/demo). 6th form gets rid of most SQL BS(joins and such. sheesh!.. lol. never used it never will..). i try 7th form, you know as kind/type (off of the kind/type table) SUPERSTRUCTURE…. yes i’m one of the top 10 DB designers in the country, if not the world… so….  … on a g-table it will work gr8 but not on a RDBMS (ms-sql_2002, only one at that time).. what did the choir leave???? i’m boring 98% of who is reading this..  sorry, but ryan, i know u understand.. this is like ‘white board’ 101 4U.. just e-me darrin at darrinburr do t co m

  14. Hi Ryan,

    I’m a new GAE developer, and now particularly interested in investigating the difference in concurrency control between the datastore and a traditional RDBMS. I looked at your presentation about the datastore in the Google IO sessions, and got some brief understanding of it. To me, doesn’t look like you guys implemented the Timestamp-based scheduling method (although you do have a timestamp attached with each row). The method I’m talking about is the “traditional” timestamp method mentioned in section 9.8.1 of the book “Database System Implementation” (http://infolab.stanford.edu/~ullman/dbsi.html) where each row should have the “read time” and the “write time”, and based on the comparison between these values and the timestamp of the transaction, the scheduler will decide how to handle the read/write request from the transaction. Is my statement true? If so, could you pls point me to some (as detailed as possible) references/papers/technical documentations/presentations about how/what method you actually used to implement concurrency control? (did you guys follow some standard method or invent your own?). I’d greatly appreciate if you could help me asap.


  15. This is my guess about the rules of your timestamp-based scheduler. If you could, pls correct where I’m wrong in here (basically I consolidated the theoretical timestamp-based scheduler with what I understand from your presentation):

    Each transaction T is assigned a timestamp TS(T) at startup. Each root entity R is given a read timestamp RTS(R) and a committed  timestamp CTS(R) (this is the timestamp mentioned in your presentation).

    1. Transaction T wants to read some entity X whose root is R (X and R may or may not be the same).
      a). If TS(T) > CTS(R): T goes ahead and performs the read (retrieved data from X is respective to CTS(R)). If TS(T) > RTS(R), set RTS(R) := TS(T); otherwise leave RTS(R) intact.
      b). If TS(T) < CTS(R): invalid read. Rollback T (abort T and restart it with a new, larger timestamp).

    2. T wants to write X.
      a). If TS(T) >= RTS(R) and TS(T) > CTS(R): T performs the write to X including writing the journal in R and applying that journal to X, excluding setting the new value for CTS(R).
      b). If TS(T) >= RTS(R), but TS(T) < CTS(R): the Thomas write rule applies here. The write by T is ignored. T is allowed to proceed without making change to R and X.
      c). if TS(T) < RTS(R): invalid write. T must be rolled back.

    3. T completes all its actions and now wants to commit. If CTS(R) at this point is still the same as when T started, it is set to TS(T); T effectively gets committed. If CTS(R) has changed, T must be rolled back.

    Note that in rolling back:
    – If T has changed RTS(R), the old value must be restored.
    – T may be retried at most n number of times (currently n is set to 4?).

    Ryan, pls give comments on what I outlined above. I’d appreciate if you could do it asap.

    Thanks a lot,

  16. Hi Ryan,

    I have further questions on this topic in the app engine group. I’d really appreciate if you could address my concerns asap when you have time.


Leave a Reply

Your email address will not be published. Required fields are marked *