Slide 1

Slide 1 text

@jsloyer! @BradleyHolt! Taking Cloud Databases to the Edge All Things Open Monday, October 19, 2015

Slide 2

Slide 2 text

@jsloyer! @BradleyHolt! Taking Cloud Databases to the Edge Bradley Holt Developer Advocate IBM Cloudant Jeff Sloyer Developer Advocate IBM Bluemix

Slide 3

Slide 3 text

@jsloyer! @BradleyHolt! Image Credit: Joan Touzet (@wohali), ASF Member, CouchDB PMC Member

Slide 4

Slide 4 text

@jsloyer! @BradleyHolt! Image Credit: Device landscape by Jeremy Keith, on Flickr Not just mobile first…!

Slide 5

Slide 5 text

@jsloyer! @BradleyHolt! Image Credit: Cloud Formation Over the Adirondacks by Bradley Holt Offline First! Because being offline shouldn't be an error condition.!

Slide 6

Slide 6 text

@jsloyer! @BradleyHolt! Doesn't ubiquitous connectivity make offline- enabled apps unnecessary?! Image Credit: Cell phone tower by Gary Lerude, on Flickr

Slide 7

Slide 7 text

@jsloyer! @BradleyHolt! No.! Image Credit: Internet Splat Map by Steve Jurvetson, on Flickr

Slide 8

Slide 8 text

@jsloyer! @BradleyHolt! Quite the opposite, in fact.! Image Credit: Tangled Network by Bruno Girin, on Flickr

Slide 9

Slide 9 text

@jsloyer! @BradleyHolt! Ubiquitous connectivity is driving the demand for 
 offline capabilities.! Image Credit: Wired by Alexandre Duret-Lutz, on Flickr

Slide 10

Slide 10 text

@jsloyer! @BradleyHolt! How?! Image Credit: connect me to BR549 by frankieleon, on Flickr

Slide 11

Slide 11 text

@jsloyer! @BradleyHolt! The Eight Fallacies of Distributed Computing 1.  The network is reliable 2.  Latency is zero 3.  Bandwidth is infinite 4.  The network is secure 5.  Topology doesn't change 6.  There is one administrator 7.  Transport cost is zero 8.  The network is homogeneous Text Credit: The Eight Fallacies of Distributed Computing by Peter Deutsch | Image Credit: Pneumatic Central by Sleestak, on Flickr

Slide 12

Slide 12 text

@jsloyer! @BradleyHolt! Image Credit: Connected version 2 by Hans Kylberg, on Flickr Offline-first is the only way 
 to achieve a true, 100% 
 always-on user experience.* ! *assuming the device is reliable!

Slide 13

Slide 13 text

@jsloyer! @BradleyHolt! Faster User Experience! Image Credit: Speed DLR on Doklands by Umberto Rotundo, on Flickr

Slide 14

Slide 14 text

@jsloyer! @BradleyHolt! Works Offline! Image Credit: Lynn Camp Prong (Explored) by AllieKF, on Flickr

Slide 15

Slide 15 text

@jsloyer! @BradleyHolt! Battery and Bandwidth! Image Credit: Panorama of the Molasses Disaster site by Boston Public Library, on Flickr

Slide 16

Slide 16 text

@jsloyer! @BradleyHolt! Offline Patterns & Anti-Patterns •  Don't return an error for no reason •  Do let users view cached/saved data •  Do synchronize data when connected

Slide 17

Slide 17 text

@jsloyer! @BradleyHolt! Offline Patterns & Anti-Patterns •  Don't return an error for no reason •  Do let users view cached/saved data •  Do synchronize data when connected

Slide 18

Slide 18 text

@jsloyer! @BradleyHolt! Offline Patterns & Anti-Patterns •  Don't return an error for no reason •  Do let users view cached/saved data •  Do synchronize data when connected

Slide 19

Slide 19 text

@jsloyer! @BradleyHolt! Offline Patterns & Anti-Patterns •  Don't return an error for no reason •  Do let users view cached/saved data •  Do synchronize data when connected

Slide 20

Slide 20 text

@jsloyer! @BradleyHolt! Introducing PouchDB

Slide 21

Slide 21 text

@jsloyer! @BradleyHolt! PouchDB •  A database in your web browser— and Node.js! •  Can synchronize with any database that implements the CouchDB Replication Protocol •  Makes create, read, update and delete operations extremely fast

Slide 22

Slide 22 text

@jsloyer! @BradleyHolt! JSON Documents {
 _id: "6EF9D2B0-13D3-1378-8D30-39E3CE0B36C2",
 _rev: "1-0b457efcf82fb29492ef927ba5b6ee15",
 type: "Feature",
 geometry: {
 type: "Point",
 coordinates: [
 -71.1028,
 42.3691
 ]
 },
 properties: {
 session_id: "3486b13f-7b8a-8a96-dfbf-9b82800e367f",
 timestamp: 1422928591717
 }
 }

Slide 23

Slide 23 text

@jsloyer! @BradleyHolt! Responsive Mobile Web Apps, Hybrid Mobile Web Apps, or Internet of Things (IoT)

Slide 24

Slide 24 text

@jsloyer! @BradleyHolt! Responsive Mobile Web Apps •  HTML5, CSS and JavaScript mobile web apps •  Responsive design •  Enhanced to enable offline usage

Slide 25

Slide 25 text

@jsloyer! @BradleyHolt! Hybrid Mobile Web Apps •  Native mobile web apps built with HTML5, CSS and JavaScript •  Good for: •  Fully-featured, cross-platform native apps •  High-fidelity prototypes

Slide 26

Slide 26 text

@jsloyer! @BradleyHolt! Internet of Things (IoT) •  Headless Node.js apps •  PouchDB includes a LevelDB adapter for use in Node.js •  Redis, Riak, and in-memory adapters are also available •  Good for: •  Internet of Things (IoT) applications •  Content delivery networks (CDN) •  Purpose-built devices Image Credit: Ethernet IoT Starter Kit

Slide 27

Slide 27 text

@jsloyer! @BradleyHolt! Apache CouchDB

Slide 28

Slide 28 text

@jsloyer! @BradleyHolt! Apache CouchDB •  JSON document database •  HTTP API •  Master-master replication

Slide 29

Slide 29 text

@jsloyer! @BradleyHolt! IBM Cloudant •  Globally distributed data layer for web and mobile applications •  MongoDB-style queries •  Advanced geospatial capabilities •  Full text search indexing

Slide 30

Slide 30 text

@jsloyer! @BradleyHolt! CouchDB Replication Protocol •  One-off, one way operation •  Peer-to-peer (masterless) •  Incremental •  Conflict detection

Slide 31

Slide 31 text

@jsloyer! @BradleyHolt! Apache Cordova, PhoneGap and Ionic

Slide 32

Slide 32 text

@jsloyer! @BradleyHolt! Apache Cordova and PhoneGap Image Credit: build.phonegap by Andrés Álvarez Iglesias, on Flickr

Slide 33

Slide 33 text

@jsloyer! @BradleyHolt! Ionic •  Mobile-optimized HTML, CSS and JavaScript components •  Builds on Apache Cordova •  Utilizes AngularJS •  CLI installable via npm

Slide 34

Slide 34 text

@jsloyer! @BradleyHolt! Using Cordova and Ionic $ npm install -g cordova ionic" $ ionic start energy-monitor tabs" $ cd energy-monitor" $ ionic platform add ios" $ ionic build ios" $ ionic emulate ios" Image Credit: Getting Started with Ionic

Slide 35

Slide 35 text

@jsloyer! @BradleyHolt! HTML5 Offline Application Cache

Slide 36

Slide 36 text

@jsloyer! @BradleyHolt! HTML5 Offline Application Cache •  Enables fully-functional offline web apps •  Stores files and assets for offline browsing •  Makes page loads very fast, even when online

Slide 37

Slide 37 text

@jsloyer! @BradleyHolt! Cache Manifest File 
 …
 
 CACHE MANIFEST
 # v1 - 2015-01-08
 index.html
 logo.png
 app.css
 app.js

Slide 38

Slide 38 text

@jsloyer! @BradleyHolt! PouchDB Code Examples

Slide 39

Slide 39 text

@jsloyer! @BradleyHolt! Installing PouchDB 
 CACHE MANIFEST
 # v2 - 2015-01-08
 index.html
 logo.png
 app.css
 app.js
 https://cdn.jsdelivr.net/pouchdb/3.5.0/pouchdb.min.js

Slide 40

Slide 40 text

@jsloyer! @BradleyHolt! Creating a Local PouchDB Database var db = new PouchDB("smart-meter");" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/01-create-local-database.js

Slide 41

Slide 41 text

@jsloyer! @BradleyHolt! Creating a Remote PouchDB Database var remoteDb = new PouchDB("https://bradley-holt.cloudant.com/smart-meter");" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/02-create-remote-database.js

Slide 42

Slide 42 text

@jsloyer! @BradleyHolt! Cross-Origin Resource Sharing (CORS) •  Enable Cross-Origin Resource Sharing (CORS) on remote database •  Browsers place security restrictions on cross-site HTTP requests •  If you run into a problem, remember this warning! Image Credit: Grunge Warning Sign - Do Not Read This Sign by Nicolas Raymond, on Flickr

Slide 43

Slide 43 text

@jsloyer! @BradleyHolt! Creating a New Document var db = new PouchDB("smart-meter");" db.put({" _id: "2014-11-12T23:27:03.794Z"," kilowatt_hours: 14" }).then(function() {" console.log("Document created");" }).catch(function(error) {" console.log(error);" });" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/04-create-document-put.js

Slide 44

Slide 44 text

@jsloyer! @BradleyHolt! Updating a Document db.put({" _id: "2014-11-12T23:27:03.794Z"," kilowatt_hours: 14" }).then(function() {" return db.get("2014-11-12T23:27:03.794Z");" }).then(function(doc) {" // Update the value for kilowatt hours" doc.kilowatt_hours = 15;" // Put the document back to the database" return db.put(doc);" }).catch(function(error) {" console.log(error);" });" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/05-update-document.js

Slide 45

Slide 45 text

@jsloyer! @BradleyHolt! Deleting a Document db.put({" _id: "2014-11-12T23:27:03.794Z"," kilowatt_hours: 14" }).then(function() {" // Get the document" return db.get("2014-11-12T23:27:03.794Z");" }).then(function(doc) {" // Remove the document from the database" return db.remove(doc);" }).catch(function(error) {" console.log(error);" });" " https://github.com/bradley-holt/offline-first/blob/master/pouchdb/06-delete-document.js

Slide 46

Slide 46 text

@jsloyer! @BradleyHolt! Querying a Database with allDocs" db.bulkDocs([" {_id: "2014-11-12T23:27:03.794Z", kilowatt_hours: 14}," {_id: "2014-11-13T00:52:01.471Z", kilowatt_hours: 15}," {_id: "2014-11-13T01:39:28.911Z", kilowatt_hours: 16}," {_id: "2014-11-13T02:52:01.471Z", kilowatt_hours: 17}" ]).then(function(result) {" // Get all documents" return db.allDocs({include_docs: true});" }).then(function(response) {" console.log(response);" }).catch(function(error) {" console.log(error);" });" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/07-query-database-all-docs.js

Slide 47

Slide 47 text

@jsloyer! @BradleyHolt! allDocs Options •  include_docs" •  conflicts" •  attachments" •  startkey" •  endkey" •  inclusive_end (true by default) •  limit" •  skip" •  descending" •  key" •  keys"

Slide 48

Slide 48 text

@jsloyer! @BradleyHolt! Querying a Database with Map/Reduce •  Most queries can be done with allDocs (in PouchDB) •  Map functions transform documents into indexes •  Reduce functions aggregate results of Map functions •  _sum" •  _count" •  _stats"

Slide 49

Slide 49 text

@jsloyer! @BradleyHolt! Querying a Database with PouchDB Find •  Based on Cloudant Query (Mango) •  MongoDB-style query language •  Define fields to index Image Credit: Mango with section on a white background by bangdoll, on Flickr

Slide 50

Slide 50 text

@jsloyer! @BradleyHolt! Replication Patterns

Slide 51

Slide 51 text

@jsloyer! @BradleyHolt! Clemmie Danyel Shelba Manuel Francis Marissa Mitchel Georgianne Garnet Audrey Kalyn Image Credit: database by Tim Morgan, on Flickr

Slide 52

Slide 52 text

@jsloyer! @BradleyHolt! 1b40d0a4 c28e6965 3fa0bee7 e83a0aeb cbdca6de ef9443e2 8e4d5a03 2e070be6 271dc425 9a278e5e f4215dfa Image Credit: database by Tim Morgan, on Flickr

Slide 53

Slide 53 text

@jsloyer! @BradleyHolt! Write-Only Replication •  Data generated on the device •  Replicate this data to the cloud from multiple users and/or devices •  Example uses: •  User updates •  Sensor data

Slide 54

Slide 54 text

@jsloyer! @BradleyHolt! Write-Only Replication var db = new PouchDB("smart-meter");" var remoteDb = new PouchDB(" "https://bradley-holt.cloudant.com/smart-meter"" );" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/08-replicate-database.js

Slide 55

Slide 55 text

@jsloyer! @BradleyHolt! Write-Only Replication db.bulkDocs([" {_id: "2014-11-12T23:27:03.794Z", kilowatt_hours: 14}," {_id: "2014-11-13T00:52:01.471Z", kilowatt_hours: 15}," {_id: "2014-11-13T01:39:28.911Z", kilowatt_hours: 16}," {_id: "2014-11-13T02:52:01.471Z", kilowatt_hours: 17}" ]).then(function(result) {" …" }).catch(function(error) {" console.log(error);" });" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/08-replicate-database.js

Slide 56

Slide 56 text

@jsloyer! @BradleyHolt! Write-Only Replication db.replicate.to(remoteDb, {" live: false," retry: false" }).on("change", function(info) {" // Replication has written a new document" console.log(info);" }).on("complete", function(info) {" // Replication has complete or been cancelled" console.log(info);" }).on("error", function(error) {" // Replication has stopped due to an unrecoverable failure" console.log(error);" });" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/08-replicate-database.js

Slide 57

Slide 57 text

@jsloyer! @BradleyHolt! Read-Only Replication •  Data generated in the cloud •  Replicate this data to multiple users and/or devices from the cloud •  Example uses: •  Weather •  Notifications

Slide 58

Slide 58 text

@jsloyer! @BradleyHolt! Read-Only Replication remoteDb.replicate.to(db, {" live: false," retry: false" }).on("change", function(info) {" // Replication has written a new document" console.log(info);" }).on("complete", function(info) {" // Replication has complete or been cancelled" console.log(info);" }).on("error", function(error) {" // Replication has stopped due to an unrecoverable failure" console.log(error);" });"

Slide 59

Slide 59 text

@jsloyer! @BradleyHolt! Bidirectional Replication •  Data generated on both the device and in the cloud •  Replicate this data to/from the cloud and to/from multiple users and/or devices •  Useful when you need to share data between users and/or devices

Slide 60

Slide 60 text

@jsloyer! @BradleyHolt! Bidirectional Replication db.sync(remoteDb, {" live: false," retry: false" }).on("change", function(info) {" // Replication has written a new document" console.log(info);" }).on("complete", function(info) {" // Replication has complete or been cancelled" console.log(info);" }).on("error", function(error) {" // Replication has stopped due to an unrecoverable failure" console.log(error);" });" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/09-replicate-database-bidirectional.js

Slide 61

Slide 61 text

@jsloyer! @BradleyHolt! Live Replication var sync = db.sync(remoteDb, {" live: true," retry: true" }).on("change", function(info) {" // Replication has written a new document" console.log(info);" }).on("complete", function(info) {" // Replication has complete or been cancelled" console.log(info);" }).on("error", function(error) {" // Replication has stopped due to an unrecoverable failure" console.log(error);" });" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/10-replicate-database-live.js

Slide 62

Slide 62 text

@jsloyer! @BradleyHolt! Filtered Replication •  Select (with a function) which documents to replicate •  Filter can be defined locally within PouchDB, or remotely on Cloudant

Slide 63

Slide 63 text

@jsloyer! @BradleyHolt! Filtered Replication db.replicate.to(remoteDb, {" filter: function(doc) {" return doc._id >= "2014-11-13T00:00:00.000Z";" }" }).on("change", function(info) {" // Replication has written a new document" console.log(info);" }).on("complete", function(info) {" // Replication has complete or been cancelled" console.log(info);" });" https://github.com/bradley-holt/offline-first/blob/master/pouchdb/12-replicate-database-filtered.js

Slide 64

Slide 64 text

@jsloyer! @BradleyHolt! Image Credits •  Joan Touzet (@wohali), ASF Member, CouchDB PMC Member •  Device landscape by Jeremy Keith, on Flickr •  Cloud Formation Over the Adirondacks by Bradley Holt •  Cell phone tower by Gary Lerude, on Flickr •  Internet Splat Map by Steve Jurvetson, on Flickr •  Tangled Network by Bruno Girin, on Flickr •  Wired by Alexandre Duret-Lutz, on Flickr •  connect me to BR549 by frankieleon, on Flickr •  Pneumatic Central by Sleestak, on Flickr •  Connected version 2 by Hans Kylberg, on Flickr •  Speed DLR on Doklands by Umberto Rotundo, on Flickr •  Lynn Camp Prong (Explored) by AllieKF, on Flickr •  Panorama of the Molasses Disaster site by Boston Public Library, on Flickr •  Ethernet IoT Starter Kit •  build.phonegap by Andrés Álvarez Iglesias, on Flickr •  Getting Started with Ionic •  Grunge Warning Sign - Do Not Read This Sign by Nicolas Raymond, on Flickr •  Mango with section on a white background by bangdoll, on Flickr •  database by Tim Morgan, on Flickr

Slide 65

Slide 65 text

@jsloyer! @BradleyHolt! Bradley Holt Developer Advocate IBM Cloudant @BradleyHolt github.com/bradley-holt Jeff Sloyer Developer Advocate IBM Bluemix @jsloyer github.com/jsloyer