Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using RethinkDB with Tornado & EventMachine

Using RethinkDB with Tornado & EventMachine

This talk demonstrates how to use the Tornado and EventMachine integration in RethinkDB's Python and Ruby drivers. It also shows how to build realtime apps in Ruby with RethinkDB and Faye.

Ryan Paul

March 30, 2015
Tweet

More Decks by Ryan Paul

Other Decks in Programming

Transcript

  1. What is RethinkDB? • Open source database for building realtime

    web applications • NoSQL database that stores schemaless JSON documents • Distributed database that is easy to scale
  2. Built for Realtime Apps • Subscribe to change notifications from

    database queries • No more polling — the database pushes changes to your app • Reduce the amount of plumbing needed to stream live updates
  3. Changefeeds • The changes command returns a cursor that receives

    updates • Each update includes the new and old value of the modified record
  4. Async Web Frameworks • New in RethinkDB 2.0 Python &

    Ruby drivers • Download the release candidate today • Official release coming in April
  5. Tornado import rethinkdb as r from tornado import ioloop, gen

    r.set_loop_type("tornado") @gen.coroutine def print_changes(): conn = yield r.connect(host="localhost", port=28015) feed = yield r.table("table").changes().run(conn) while (yield feed.fetch_next()) change = yield feed.next() print(change) ioloop.IOLoop.current().add_callback(print_changes)
  6. Tornado import rethinkdb as r from tornado import ioloop, gen

    r.set_loop_type("tornado") @gen.coroutine def print_changes(): conn = yield r.connect(host="localhost", port=28015) feed = yield r.table("table").changes().run(conn) while (yield feed.fetch_next()) change = yield feed.next() print(change) ioloop.IOLoop.current().add_callback(print_changes) Configure the event loop
  7. Tornado import rethinkdb as r from tornado import ioloop, gen

    r.set_loop_type("tornado") @gen.coroutine def print_changes(): conn = yield r.connect(host="localhost", port=28015) feed = yield r.table("table").changes().run(conn) while (yield feed.fetch_next()) change = yield feed.next() print(change) ioloop.IOLoop.current().add_callback(print_changes) Add the coroutine decorator
  8. Tornado import rethinkdb as r from tornado import ioloop, gen

    r.set_loop_type("tornado") @gen.coroutine def print_changes(): conn = yield r.connect(host="localhost", port=28015) feed = yield r.table("table").changes().run(conn) while (yield feed.fetch_next()) change = yield feed.next() print(change) ioloop.IOLoop.current().add_callback(print_changes) Connect to the database
  9. Tornado import rethinkdb as r from tornado import ioloop, gen

    r.set_loop_type("tornado") @gen.coroutine def print_changes(): conn = yield r.connect(host="localhost", port=28015) feed = yield r.table("table").changes().run(conn) while (yield feed.fetch_next()) change = yield feed.next() print(change) ioloop.IOLoop.current().add_callback(print_changes) Perform the ReQL query
  10. Tornado import rethinkdb as r from tornado import ioloop, gen

    r.set_loop_type("tornado") @gen.coroutine def print_changes(): conn = yield r.connect(host="localhost", port=28015) feed = yield r.table("table").changes().run(conn) while (yield feed.fetch_next()) change = yield feed.next() print(change) ioloop.IOLoop.current().add_callback(print_changes) Iterate over changefeed changes
  11. Tornado import rethinkdb as r from tornado import ioloop, gen

    r.set_loop_type("tornado") @gen.coroutine def print_changes(): conn = yield r.connect(host="localhost", port=28015) feed = yield r.table("table").changes().run(conn) while (yield feed.fetch_next()) change = yield feed.next() print(change) ioloop.IOLoop.current().add_callback(print_changes) Fetch the latest change
  12. Tornado import rethinkdb as r from tornado import ioloop, gen

    r.set_loop_type("tornado") @gen.coroutine def print_changes(): conn = yield r.connect(host="localhost", port=28015) feed = yield r.table("table").changes().run(conn) while (yield feed.fetch_next()) change = yield feed.next() print(change) ioloop.IOLoop.current().add_callback(print_changes) Print the change to stdout
  13. Tornado import rethinkdb as r from tornado import ioloop, gen

    r.set_loop_type("tornado") @gen.coroutine def print_changes(): conn = yield r.connect(host="localhost", port=28015) feed = yield r.table("table").changes().run(conn) while (yield feed.fetch_next()) change = yield feed.next() print(change) ioloop.IOLoop.current().add_callback(print_changes) Run coroutine in the background
  14. EventMachine require "rethinkdb" include RethinkDB::Shortcuts conn = r.connect host: "localhost",

    port: 28015 EM.run do r.table("table").changes.em_run(conn) do |err, change| puts change end end
  15. EventMachine require "rethinkdb" include RethinkDB::Shortcuts conn = r.connect host: "localhost",

    port: 28015 EM.run do r.table("table").changes.em_run(conn) do |err, change| puts change end end Connect to the database
  16. EventMachine require "rethinkdb" include RethinkDB::Shortcuts conn = r.connect host: "localhost",

    port: 28015 EM.run do r.table("table").changes.em_run(conn) do |err, change| puts change end end Create an EventMachine block
  17. EventMachine require "rethinkdb" include RethinkDB::Shortcuts conn = r.connect host: "localhost",

    port: 28015 EM.run do r.table("table").changes.em_run(conn) do |err, change| puts change end end Perform the ReQL query
  18. EventMachine require "rethinkdb" include RethinkDB::Shortcuts conn = r.connect host: "localhost",

    port: 28015 EM.run do r.table("table").changes.em_run(conn) do |err, change| puts change end end Print the change to stdout
  19. Faye Framework • Open source pub/sub framework for realtime messaging

    • Communication between frontend and backend • Supports Ruby and Node.js on the backend
  20. Faye Framework EM.run do ... App = Faye::RackAdapter.new Sinatra::Application, mount:

    "/faye" conn = r.connect host: "localhost", port: 28015 r.table("todo").changes.em_run(conn) do |err, change| App.get_client.publish("/todo/update", change) end ... end Server-side Ruby code
  21. Faye Framework EM.run do ... App = Faye::RackAdapter.new Sinatra::Application, mount:

    "/faye" conn = r.connect host: "localhost", port: 28015 r.table("todo").changes.em_run(conn) do |err, change| App.get_client.publish("/todo/update", change) end ... end Initialize Faye and bind URL route
  22. Faye Framework EM.run do ... App = Faye::RackAdapter.new Sinatra::Application, mount:

    "/faye" conn = r.connect host: "localhost", port: 28015 r.table("todo").changes.em_run(conn) do |err, change| App.get_client.publish("/todo/update", change) end ... end Connect to the database
  23. Faye Framework EM.run do ... App = Faye::RackAdapter.new Sinatra::Application, mount:

    "/faye" conn = r.connect host: "localhost", port: 28015 r.table("todo").changes.em_run(conn) do |err, change| App.get_client.publish("/todo/update", change) end ... end Perform the ReQL query
  24. Faye Framework EM.run do ... App = Faye::RackAdapter.new Sinatra::Application, mount:

    "/faye" conn = r.connect host: "localhost", port: 28015 r.table("todo").changes.em_run(conn) do |err, change| App.get_client.publish("/todo/update", change) end ... end Publish the update to a channel