Google Back to Front
From Gears to App Engine, and beyond
Interesting, passionate, times
We
                      Believe...




The Web is the platform of today,
      and of the future
Act One
The Client
Top Grossing Film of 1957   Top Grossing Film of 2007
“Gimme Offline!”
It takes too long to update the Web
What is the philosophy?
          Do for offline what XMLHttpRequest did for web apps



     Ajax Libraries               ...
Database
                             Embedded using SQLite
                            Contributed Full Text Search



va...
GearsDB
                       Abstract over the API

var bob = {id: 3, name: 'Bob', url: 'http://bob.com', description: '...
GearsORM
         Are we going to get a GearsHibernate?


var Person = new GearsOrm.Model(quot;Personquot;, {
  firstName: ...
GearShift
              DB Migrations for Gears

Gearshift.rules[1] = {
   // create the demo table
   up: function() {
  ...
Database Tools
Buxfer
Full Text Search
• Gears added FTS2 to SQLite
• Create the database
 db.execute('CREATE VIRTUAL TABLE recipe USING fts2
 (...
The Digg Oracle
Local Server
A mini-web server that groks 200 and 304
ResourceStore
                                Manually Capturing
var pageFiles = [
   location.pathname,
   'gears_base.js...
ManagedResourceStore
                                                   JSON Me
{
    // version of the manifest file forma...
HTML 5
                                 Offline in General

<html application=”manifest-of-urls.txt”>

<html application>
“...
Future


                 Present
                                                 Ab
                                    ...
Mouse Moved

                                 Mouse Pressed

                                 Mouse Released

            ...
1




                                     Browser




User Interface                    Message Passing




             ...
Worker Pool Code
function nextPrime(n) {
   // TODO: New top-secret prime-finding algorithm goes here.
   google.gears.work...
JavaScript Read Write APIs
Desktop
                                   Shortcuts




var desktop = google.gears.factory.create('beta.desktop');
deskto...
Notification API
                                  Growl for the Web



var notifier = google.gears.factory.create('beta.not...
Location API
                                      Even on a laptop?


// Getting the object
var location = google.gears.f...
Audio API
                                    Play and Record


// play
var audio = google.gears.factory.create('beta.audi...
File System API



                Blob API




            Resumable HTTP




Don’t you want a better File Upload?
Gears: Open Source Update
  Mechanism for the Web
Don't forget, RIA's have rich
    internet back-ends (RIBs?)




Jonathan Schwartz
CEO, Sun Microsystems
Act Two
The Server
Google App Engine
Running Web Apps on Google’s Infrastructure




                                              • Fully-in...
Google App Engine
Challenges
Google App Engine
Easy to use, Easy to scale, Free to start
Develop locally. Deploy to Google. Launch.
Develop locally. Deploy to Google. Launch.




                                   Deploy
Develop locally. Deploy to Google. Launch.
Develop locally.




     • Google App Engine SDK is open source
     • Simulates production environment
     •dev_appserv...
Hello World
Simplest output, simplest config




# helloworld.py
print quot;Content-Type: text/htmlquot;
print
print quot;...
loadcontacts

                          var contacts = [
                            { id: 1, name: ‘Dion Almaer’, ... },
...
threads
                  sockets
                    files
                foreground




the snake is almost there
from django import v0_96 as django
Store data
Scalable, and not like a RDBMS




                                 Wow, that's a
                             ...
Data Model
 Just an object




from google.appengine.ext import db

class Story(db.Model):
  title = db.StringProperty()
 ...
GQL
Our query language




 SELECT *
 FROM Story
 WHERE title = 'App Engine Launch'
 AND author = :current_user
 AND ratin...
Run the queries
Beyond GQL




 Story.gql(GQL_FROM_BEFORE,
   current_user = users.get_current_user())

 query = Story.all...
Inserts
Manipulating the data




 story = Story(
   title = 'Morning Glory',
   body = '....',
   author = users.get_curr...
Call Web Services
URL Fetch API
  Aint no urllib2




from google.appengine.api import urlfetch

some_feed = urlfetch.fetch('http://somesite...
Authenticate to Google
OpenID provider.... available
Users API
But you can do your own thing too of course...




 from google.appengine.api import users

 current_user = user...
Send Email
Email API
 No SMTP config required




from google.appengine.api import mail

def post(self):
  email_body = self.request....
Manipulate Images
Image Manipulation API
 No SMTP config required




# in model
avatar = db.BlobProperty()

# in handler
avatar = images.re...
Memcache Support
In-memory distributed cache
Memcache API
    In-memory distributed cache


from google.appengine.api import memcache

def get_data():
  data = memcach...
Google App Engine
Areas of Work, Including…



• Offline Processing
• Rich Media Support
  – e.g., large file upload / dow...
Use it as you will
No need to go whole hog
Your Application




                   Web Services
Python
                              Runtime



                                             Web
        Configuration
   ...
Act Three
And there’s more
What if popular JavaScript libraries
      were available and shared in the browser?


1   Now hosting open source JavaScr...
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Google Back To Front: From Gears to App Engine and Beyond
Upcoming SlideShare
Loading in …5
×

Google Back To Front: From Gears to App Engine and Beyond

10,194 views

Published on

I had the privilege of giving a Yahoo! Tech Talk at their HQ in Sunnyvale. I spoke on Gears, App Engine, and other technologies such as the Ajax Libraries API and Doctype.

Published in: Technology
1 Comment
13 Likes
Statistics
Notes
No Downloads
Views
Total views
10,194
On SlideShare
0
From Embeds
0
Number of Embeds
25
Actions
Shares
0
Downloads
332
Comments
1
Likes
13
Embeds 0
No embeds

No notes for slide

Google Back To Front: From Gears to App Engine and Beyond

  1. Google Back to Front From Gears to App Engine, and beyond
  2. Interesting, passionate, times
  3. We Believe... The Web is the platform of today, and of the future
  4. Act One The Client
  5. Top Grossing Film of 1957 Top Grossing Film of 2007
  6. “Gimme Offline!”
  7. It takes too long to update the Web
  8. What is the philosophy? Do for offline what XMLHttpRequest did for web apps Ajax Libraries Gears Libraries Dojo, jQuery, Prototype, GWT Dojo Offline, GWT XMLHttpRequest Gears Open Web Open Web
  9. Database Embedded using SQLite Contributed Full Text Search var db = google.gears.factory.create('beta.database', '1.0'); db.open('database-demo'); db.execute('create table if not exists Demo (Phrase varchar(255), Timestamp int)'); db.execute('insert into Demo values (?, ?)', [phrase, currTime]);
  10. GearsDB Abstract over the API var bob = {id: 3, name: 'Bob', url: 'http://bob.com', description: 'whee'}; db.insertRow('person', bob); db.insertRow('person', bob, 'name = ?', ['Bob']); db.selectAll('select * from person', null, function(person) { document.getElementById('selectAll').innerHTML += ' ' + person.name; }); var person = db.selectRow('person', 'id = 1'); // update person.name = 'Harry'; db.updateRow('person', person); person = db.selectRow('person', 'id = 1'); // force person.name = 'Sally'; db.forceRow('person', person); person = db.selectRow('person', 'id = 1'); db.deleteRow('person', bob);
  11. GearsORM Are we going to get a GearsHibernate? var Person = new GearsOrm.Model(quot;Personquot;, { firstName: GearsOrm.Fields.String({maxLength:25}), lastName: GearsOrm.Fields.String({maxLength:25}) }); GearsORM.Transaction(function() { “While developing transaction support for new Person({name:quot;Johnquot;}).save(); GearsORM i had to write a test, in that test it execute 100 inserts and 100 updates, this test take new Person({name:quot;Doequot;}).save(); about 15 seconds for the inserts and about 10 seconds for the updates without transactions,when }); using transactions for each set it takes about 377ms for the inserts and 200ms for the updates that is about Person.select(quot;firstName = 'Uriel'quot;); 39 times faster!” Person.count(quot;lastName = ?quot;,[quot;Katzquot;])
  12. GearShift DB Migrations for Gears Gearshift.rules[1] = { // create the demo table up: function() { return this.e(quot;CREATE TABLE demo_table ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(30), movie VARCHAR(30) )quot;).success; }, down: function() { return this.e(quot;DROP TABLE demo_tablequot;).success; } };
  13. Database Tools
  14. Buxfer
  15. Full Text Search • Gears added FTS2 to SQLite • Create the database db.execute('CREATE VIRTUAL TABLE recipe USING fts2 (dish, ingredients)'); • Search the database db.execute('SELECT dish FROM recipe WHERE recipe MATCH ?', ['tomatoes']); Fun queries: dish:stew tomatoes Find rows with 'stew' in the dish field, and 'tomatoes' in any field.
  16. The Digg Oracle
  17. Local Server A mini-web server that groks 200 and 304
  18. ResourceStore Manually Capturing var pageFiles = [ location.pathname, 'gears_base.js', '../scripts/gears_db.js', ‘foo.html’ ]; try { localServer = google.gears.factory.create('beta.localserver', '1.0'); } catch (e) { alert('Could not create local server: ' + e.message); return; } var store = localServer.openStore(this.storeName) || localServer.createStore(this.storeName); store.capture(pageFiles, function(url, success, captureId) { console.log(url + ' capture ' + (success ? 'succeeded' : 'failed')); });
  19. ManagedResourceStore JSON Me { // version of the manifest file format quot;betaManifestVersionquot;: 1, // version of the set of resources described in this manifest file quot;versionquot;: quot;my_version_stringquot;, // optional // If the store specifies a requiredCookie, when a request would hit // an entry contained in the manifest except the requiredCookie is // not present, the local server responds with a redirect to this URL. quot;redirectUrlquot;: quot;login.htmlquot;, // URLs to be cached (URLs are given relative to the manifest URL) quot;entriesquot;: [ { quot;urlquot;: quot;main.htmlquot;, quot;srcquot;: quot;main_offline.htmlquot; }, { quot;urlquot;: quot;.quot;, quot;redirectquot;: quot;main.htmlquot; }, { quot;urlquot;: quot;main.jsquot; } { quot;urlquot;: quot;formHandler.htmlquot;, quot;ignoreQueryquot;: true }, ] }
  20. HTML 5 Offline in General <html application=”manifest-of-urls.txt”> <html application> “There’s a concept of an application cache. An application cache is a group of resources, the group being identified by a URI (which typically happens to resolve to a manifest). Resources in a cache are either top-level or not; top-level resources are those that are HTML or XML and when parsed with scripting disabled have with the value of the attribute pointing to the same URI as identifies the cache. When you visit a page you first check to see if you have that page in a cache as a known top-level page.”
  21. Future Present Ab l edg eeding ev of H ersion TML Past 5! HTML 5 Gears • Standards • Implementation • Long term • Battle hardened • All browsers • A place for innovation • Cross browser • No plugin • Plugin
  22. Mouse Moved Mouse Pressed Mouse Released Key Pressed Operating System Key Released Event Queue al enti ck Pot lene t Bot JavaScript Web Browsing Browser
  23. 1 Browser User Interface Message Passing 2 3 WorkerPool WorkerPool
  24. Worker Pool Code function nextPrime(n) { // TODO: New top-secret prime-finding algorithm goes here. google.gears.workerPool.sendMessage(result); } var pool = google.gears.factory.create('beta.workerpool', '1.0'); pool.onmessage = function(message) { alert('next prime is: ' + message); } var worker = pool.createWorker(String(nextPrime) + '; nextPrime()');
  25. JavaScript Read Write APIs
  26. Desktop Shortcuts var desktop = google.gears.factory.create('beta.desktop'); desktop.createShortcut(quot;Test Applicationquot;, quot;An application at http://www.test.com/index.htmlquot;, quot;http://www.test.com/index.htmlquot;, {quot;16x16quot;: quot;http://www.test.com/icon16x16.pngquot;, quot;32x32quot;: quot;http://www.test.com/icon32x32.pngquot;, quot;48x48quot;: quot;http://www.test.com/icon48x48.pngquot;, quot;128x128quot;: quot;http://www.test.com/icon128x128.pngquot;});
  27. Notification API Growl for the Web var notifier = google.gears.factory.create('beta.notifier', '1.0'); notifier.notify({ application: quot;My Appquot;, title: 'warning', description: 'some text', priority: 2, sticky: 'True', password: 'Really Secure', });
  28. Location API Even on a laptop? // Getting the object var location = google.gears.factory.create( quot;beta.locationquot;, quot;1.0quot; ); // Setting up a callback to handle quot;location changedquot; events location.onlocationstatechanged = function() { if (this.state == COMPLETE) { SetStatusText(quot;Location accuracy:quot;, this.accuracy); MoveMap(this.latitude, this.longitude); } } location.startLocationUpdates();
  29. Audio API Play and Record // play var audio = google.gears.factory.create('beta.audio'); audio.src = 'http://blahblahblob.com/sampleaudio.wav'; audio.load(); audio.play(); // record var recorder = google.gears.factory.create('beta.audiorecorder'); recorder.destination = <http post url> recorder.autoStream = true; recorder.record(); //asynchronous call
  30. File System API Blob API Resumable HTTP Don’t you want a better File Upload?
  31. Gears: Open Source Update Mechanism for the Web
  32. Don't forget, RIA's have rich internet back-ends (RIBs?) Jonathan Schwartz CEO, Sun Microsystems
  33. Act Two The Server
  34. Google App Engine Running Web Apps on Google’s Infrastructure • Fully-integrated application environment • Language agnostic runtime Python for now • Free quota of 5M pageviews per month code.google.com/appengine
  35. Google App Engine Challenges
  36. Google App Engine Easy to use, Easy to scale, Free to start
  37. Develop locally. Deploy to Google. Launch.
  38. Develop locally. Deploy to Google. Launch. Deploy
  39. Develop locally. Deploy to Google. Launch.
  40. Develop locally. • Google App Engine SDK is open source • Simulates production environment •dev_appserver.py myapp •appcfg.py update myapp
  41. Hello World Simplest output, simplest config # helloworld.py print quot;Content-Type: text/htmlquot; print print quot;Hello, world!quot; # app.yaml application: dalmaer-helloworld version: 1 runtime: python api_version: 1 handlers: - url: /.* script: helloworld.py
  42. loadcontacts var contacts = [ { id: 1, name: ‘Dion Almaer’, ... }, { id: 2, name: ‘Ben Galbraith’, ... }, savecontact ] name=’Dion A Lamer’ email=’dion@almaer.com’ Web Services
  43. threads sockets files foreground the snake is almost there
  44. from django import v0_96 as django
  45. Store data Scalable, and not like a RDBMS Wow, that's a big table!
  46. Data Model Just an object from google.appengine.ext import db class Story(db.Model): title = db.StringProperty() body = db.TextProperty(required=True) author = db.UserProperty(required=True) created = db.DateTimeProperty(auto_now_add=True) rating = db.RatingProperty() # Many other types: BlobProperty, ReferenceProperty, EmailProperty, PhoneProperty, IMProperty, PostallAddressProperty, etc.
  47. GQL Our query language SELECT * FROM Story WHERE title = 'App Engine Launch' AND author = :current_user AND rating >= 10 ORDER BY rating, created DESC
  48. Run the queries Beyond GQL Story.gql(GQL_FROM_BEFORE, current_user = users.get_current_user()) query = Story.all() query.filter('title =', 'Foo') .order('-date') .ancestor(key)
  49. Inserts Manipulating the data story = Story( title = 'Morning Glory', body = '....', author = users.get_current_user(), ) story.put() # save or update story.delete() # delete if saved
  50. Call Web Services
  51. URL Fetch API Aint no urllib2 from google.appengine.api import urlfetch some_feed = urlfetch.fetch('http://somesite.com/rss') if some_feed.status_code == 200: self.response.out.write(some_feed.content) 53 421
  52. Authenticate to Google OpenID provider.... available
  53. Users API But you can do your own thing too of course... from google.appengine.api import users current_user = users.get_current_user() if not current_user: self.redirect(users.create_login_url('/ current_url')) nickname = current_user.nickname() email = current_user.email() if users.is_current_user_admin(): ...
  54. Send Email
  55. Email API No SMTP config required from google.appengine.api import mail def post(self): email_body = self.request.get('email_body') sender = users.get_current_user().email mail.send_mail(sender=sender, to='marce@google.com', subject='Wiki Page', body=email_body) self.response.out.write('Email Sent')
  56. Manipulate Images
  57. Image Manipulation API No SMTP config required # in model avatar = db.BlobProperty() # in handler avatar = images.resize(self.request.get(quot;imgquot;), 32, 32) # available resize crop rotate horizontal_flip vertical_flip im_feeling_lucky :)
  58. Memcache Support In-memory distributed cache
  59. Memcache API In-memory distributed cache from google.appengine.api import memcache def get_data(): data = memcache.get(quot;keyquot;) if data is not None: return data else: data = self.query_for_data() memcache.add(quot;keyquot;, data, 60) return data # Set several values, overwriting any existing values for these keys. memcache.set_multi({ quot;USA_98105quot;: quot;rainingquot;, quot;USA_94105quot;: quot;foggyquot;, quot;USA_94043quot;: quot;sunnyquot; }, key_prefix=quot;weather_quot;, time=3600) # Atomically increment an integer value. memcache.set(key=quot;counterquot;, 0) memcache.incr(quot;counterquot;) memcache.incr(quot;counterquot;) memcache.incr(quot;counterquot;)
  60. Google App Engine Areas of Work, Including… • Offline Processing • Rich Media Support – e.g., large file upload / download • Add’l Infrastructure Services • What would you like to see? 74
  61. Use it as you will No need to go whole hog
  62. Your Application Web Services
  63. Python Runtime Web Configuration Applications Static Files URL Fetch API Google App Engine Email API Users API Memcache API Image API
  64. Act Three And there’s more
  65. What if popular JavaScript libraries were available and shared in the browser? 1 Now hosting open source JavaScript libraries at Google Starting with: Prototype, Script.aculo.us, jQuery, Dojo, Mootools Accepting requests for other open source libraries Can access directly: ajax.googleapis.com/ajax/lib/prototype?v=1.6.0.2&packed=false Can access via AJAX API Loader: google.load(“prototype”, “1.6”); 2 Other features Automatic compression Minification of libraries Not tied to Google Code

×